-
+
@@ -193,20 +181,17 @@ exports[`CdrSurfaceSelection > snapshot test > renders correctly 1`] = `
-
+
diff --git a/src/components/surfaceSelection/__tests__/__snapshots__/CdrSurfaceSelectionLayout.spec.js.snap b/src/components/surfaceSelection/__tests__/__snapshots__/CdrSurfaceSelectionLayout.spec.js.snap
deleted file mode 100644
index 68d749481..000000000
--- a/src/components/surfaceSelection/__tests__/__snapshots__/CdrSurfaceSelectionLayout.spec.js.snap
+++ /dev/null
@@ -1,34 +0,0 @@
-// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-
-exports[`CdrSurfaceSelectionLayout > orientation test > shows horizontal 1`] = `
-
-
-
-
-
-`;
-
-exports[`CdrSurfaceSelectionLayout > orientation test > shows vertical 1`] = `
-
-
-
-
-
-`;
-
-exports[`CdrSurfaceSelectionLayout > snapshot test > renders correctly 1`] = `
-
-
-
-
-
-`;
diff --git a/src/components/surfaceSelection/examples/SurfaceSelection.vue b/src/components/surfaceSelection/examples/SurfaceSelection.vue
index 64f763f51..375867e2b 100644
--- a/src/components/surfaceSelection/examples/SurfaceSelection.vue
+++ b/src/components/surfaceSelection/examples/SurfaceSelection.vue
@@ -27,12 +27,13 @@ const examples = computed(
loading: loading.value,
role: 'checkbox',
class: 'example__wide',
+ layout: { columns: ['auto', 1] },
},
{
checked: false,
loading: loading.value,
role: 'checkbox',
- orientation: 'vertical',
+ layout: { flow: 'row' },
},
],
);
@@ -64,16 +65,16 @@ const examples = computed(
...
- Auto
- Auto
+ auto
+ auto
- Auto
- 100%
+ auto
+ 1fr
- orientation
- vertical
+ layout flow
+ set to "row"
@@ -107,14 +108,19 @@ const examples = computed(
}
&__wide {
- width: 200px;
+ width: 300px;
}
- &__100 {
- width: 100%;
+ &__remaining {
background: black;
color: white;
text-align: center;
}
+
+ &__color-row {
+ padding: .2rem .8rem;
+ color: white;
+ background: black;
+ }
}
diff --git a/src/components/surfaceSelection/styles/CdrSurfaceSelectionLayout.module.scss b/src/components/surfaceSelection/styles/CdrSurfaceSelectionLayout.module.scss
deleted file mode 100644
index 27392f06b..000000000
--- a/src/components/surfaceSelection/styles/CdrSurfaceSelectionLayout.module.scss
+++ /dev/null
@@ -1,6 +0,0 @@
-@import './vars/CdrSurfaceSelectionLayout.vars';
-@import '../../surface/styles/vars/CdrSurface.vars';
-
-.cdr-surface-selection-layout {
- @include cdr-surface-selection-layout-base-mixin;
-}
diff --git a/src/components/surfaceSelection/styles/vars/CdrSurfaceSelectionLayout.vars.scss b/src/components/surfaceSelection/styles/vars/CdrSurfaceSelectionLayout.vars.scss
deleted file mode 100644
index 6d00a6be6..000000000
--- a/src/components/surfaceSelection/styles/vars/CdrSurfaceSelectionLayout.vars.scss
+++ /dev/null
@@ -1,14 +0,0 @@
-@import '../../../../styles/settings/index';
-
-@mixin cdr-surface-selection-layout-base-mixin() {
- display: flex;
- gap: $cdr-space-three-eighth-x;
-
- &--horizontal {
- flex-direction: row;
- }
-
- &--vertical {
- flex-direction: column;
- }
-}
diff --git a/src/dev/router.js b/src/dev/router.js
index 7622e57c3..f05f89dd1 100644
--- a/src/dev/router.js
+++ b/src/dev/router.js
@@ -40,6 +40,7 @@ const routes = [
{ path: '/inputs', name: 'Input', component: Examples.inputs },
{ path: '/kicker', name: 'Kicker', component: Examples.kicker },
{ path: '/landing-lead', name: 'Landing Lead', component: Examples.landingLead },
+ { path: '/layout', name: 'Layout', component: Examples.layout },
{ path: '/links', name: 'Links', component: Examples.links },
{ path: '/lists', name: 'Lists', component: Examples.list },
{ path: '/modals', name: 'Modals', component: Examples.modal },
diff --git a/src/lib.ts b/src/lib.ts
index 04120c1ee..68c8f4de5 100644
--- a/src/lib.ts
+++ b/src/lib.ts
@@ -17,13 +17,13 @@ export { default as CdrFulfillmentTile } from './components/fulfillmentTile/CdrF
export { default as CdrFulfillmentTileContent } from './components/fulfillmentTile/CdrFulfillmentTileContent.vue';
export { default as CdrFulfillmentTileHeader } from './components/fulfillmentTile/CdrFulfillmentTileHeader.vue';
export { default as CdrFulfillmentTileIcon } from './components/fulfillmentTile/CdrFulfillmentTileIcon.vue';
-export { default as CdrFulfillmentTileLayout } from './components/fulfillmentTile/CdrFulfillmentTileLayout.vue';
export { default as CdrGrid } from './components/grid/CdrGrid.vue';
export { default as CdrIcon } from './components/icon/CdrIcon.vue';
export { default as CdrImg } from './components/image/CdrImg.vue';
export { default as CdrInput } from './components/input/CdrInput.vue';
export { default as CdrKicker } from './components/kicker/CdrKicker.vue';
export { default as CdrLandingLead } from './components/landingLead/CdrLandingLead.vue';
+export { default as CdrLayout } from './components/layout/CdrLayout.vue';
export { default as CdrLink } from './components/link/CdrLink.vue';
export { default as CdrList } from './components/list/CdrList.vue';
export { default as CdrModal } from './components/modal/CdrModal.vue';
@@ -39,7 +39,6 @@ export { default as CdrSkeletonBone } from './components/skeleton/CdrSkeletonBon
export { default as CdrSplitSurface } from './components/splitSurface/CdrSplitSurface.vue';
export { default as CdrSurface } from './components/surface/CdrSurface.vue';
export { default as CdrSurfaceSelection } from './components/surfaceSelection/CdrSurfaceSelection.vue';
-export { default as CdrSurfaceSelectionLayout } from './components/surfaceSelection/CdrSurfaceSelectionLayout.vue';
export { default as CdrTable } from './components/table/CdrTable.vue';
export { default as CdrTabPanel } from './components/tabs/CdrTabPanel.vue';
export { default as CdrTabs } from './components/tabs/CdrTabs.vue';
diff --git a/src/styles/cdr-reset.scss b/src/styles/cdr-reset.scss
index 0613b2dec..5c4a4e84c 100644
--- a/src/styles/cdr-reset.scss
+++ b/src/styles/cdr-reset.scss
@@ -45,6 +45,8 @@ body {
/* cdr-color-background-primary */
background-color: #ffffff;
+ container-name: cdr-body;
+ container-type: inline-size;
}
h1,
diff --git a/src/styles/settings/background.vars.scss b/src/styles/settings/background.vars.scss
new file mode 100644
index 000000000..1af5e711d
--- /dev/null
+++ b/src/styles/settings/background.vars.scss
@@ -0,0 +1,21 @@
+// Generates a background property with a predictable format for overriding
+@mixin cdr-background-mixin($options, $component, $modifier: 'undefined', $state: 'undefined') {
+ $statePart: '';
+ $modifierPart: '';
+
+ @if $state != 'undefined' {
+ $statePart: -#{$state};
+ }
+
+ @if $modifier != 'undefined' {
+ $modifierPart: -#{$modifier};
+ }
+
+ background: var(
+ --cdr-#{$component}#{$modifierPart}-background-color#{$statePart},
+ var(
+ --cdr-color-background-#{$component}#{$modifierPart}#{$statePart},
+ #{map.get($options, $modifier, $state)}
+ )
+ );
+}
diff --git a/src/styles/settings/border.vars.scss b/src/styles/settings/border.vars.scss
new file mode 100644
index 000000000..b8a7918d0
--- /dev/null
+++ b/src/styles/settings/border.vars.scss
@@ -0,0 +1,68 @@
+// Available border widths for Surface and child components
+$border-widths: (
+ 'zero': $cdr-space-zero,
+ 'sixteenth-x': $cdr-space-sixteenth-x,
+ 'eighth-x': $cdr-space-eighth-x,
+ 'three-sixteenth-x': $cdr-space-three-sixteenth-x,
+ 'quarter-x': $cdr-space-quarter-x,
+ 'three-eighth-x': $cdr-space-three-eighth-x,
+);
+
+// Available border styles for Surface and child components
+$border-styles: 'dotted', 'dashed', 'solid';
+
+// Generates a border color CSS variable that can be used by a shorthand border
+@mixin cdr-border-color-mixin($options, $component, $modifier: 'undefined', $state: 'undefined') {
+ $statePart: '';
+ $modifierPart: '';
+
+ @if $state != 'undefined' {
+ $statePart: -#{$state};
+ }
+
+ @if $modifier != 'undefined' {
+ $modifierPart: -#{$modifier};
+ }
+
+ --cdr-#{$component}-border-color-default: var(
+ --cdr-#{$component}#{$modifierPart}-border-color#{$statePart},
+ var(
+ --cdr-color-border-#{$component}#{$modifierPart}#{$statePart},
+ #{map.get($options, $modifier, $state)}
+ )
+ );
+}
+
+// Generates a border width CSS variable that can be used by a shorthand border
+@mixin cdr-border-width-mixin($component, $key) {
+ --cdr-#{$component}-border-width-default: var(
+ --cdr-#{$component}-border-width,
+ var(--cdr-space-inset-#{$key}, #{map.get($border-widths, $key)})
+ );
+}
+
+// Generates a border style CSS variable that can be used by a shorthand border
+@mixin cdr-border-style-mixin($component, $key) {
+ --cdr-#{$component}-border-style-default: var(
+ --cdr-#{$component}-border-style,
+ var(--cdr-border-style-#{$key}, #{$key})
+ );
+}
+
+// Generates a border property with a predictable format for overriding
+@mixin cdr-border-mixin($component) {
+ position: relative;
+
+ &::after {
+ border-radius: var(--cdr-#{$component}-radius-default);
+ pointer-events: none;
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ content: '';
+ border: var(--cdr-#{$component}-border-width-default)
+ var(--cdr-#{$component}-border-style-default) var(--cdr-#{$component}-border-color-default);
+ }
+}
diff --git a/src/styles/settings/index.scss b/src/styles/settings/index.scss
index 73b95ce4a..62e62f3c1 100644
--- a/src/styles/settings/index.scss
+++ b/src/styles/settings/index.scss
@@ -7,117 +7,8 @@ $cdr-warn: false;
@import './options.vars';
@import './visibility.vars';
@import './fluid.vars';
-
-$border-widths: (
- 'zero': $cdr-space-zero,
- 'sixteenth-x': $cdr-space-inset-sixteenth-x,
- 'eighth-x': $cdr-space-inset-eighth-x,
- 'three-sixteenth-x': $cdr-space-inset-three-sixteenth-x,
- 'quarter-x': $cdr-space-inset-quarter-x,
- 'three-eighth-x': $cdr-space-inset-three-eighth-x,
-);
-$border-styles: 'dotted', 'dashed', 'solid';
-$radii: (
- 'sharp': $cdr-radius-sharp,
- 'soft': $cdr-radius-soft,
- 'softer': $cdr-radius-softer,
- 'softest': $cdr-radius-softest,
- 'round': $cdr-radius-round,
-);
-$shadows: (
- 'flat': $cdr-prominence-flat,
- 'raised': $cdr-prominence-raised,
- 'elevated': $cdr-prominence-elevated,
- 'floating': $cdr-prominence-floating,
- 'lifted': $cdr-prominence-lifted,
-);
-
-@mixin cdr-background-mixin($options, $component, $modifier: 'undefined', $state: 'undefined') {
- $statePart: '';
- $modifierPart: '';
-
- @if $state != 'undefined' {
- $statePart: -#{$state};
- }
-
- @if $modifier != 'undefined' {
- $modifierPart: -#{$modifier};
- }
-
- background: var(
- --cdr-#{$component}#{$modifierPart}-background-color#{$statePart},
- var(
- --cdr-color-background-#{$component}#{$modifierPart}#{$statePart},
- #{map.get($options, $modifier, $state)}
- )
- );
-}
-
-@mixin cdr-border-color-mixin($options, $component, $modifier: 'undefined', $state: 'undefined') {
- $statePart: '';
- $modifierPart: '';
-
- @if $state != 'undefined' {
- $statePart: -#{$state};
- }
-
- @if $modifier != 'undefined' {
- $modifierPart: -#{$modifier};
- }
-
- --cdr-#{$component}-border-color-default: var(
- --cdr-#{$component}#{$modifierPart}-border-color#{$statePart},
- var(
- --cdr-color-border-#{$component}#{$modifierPart}#{$statePart},
- #{map.get($options, $modifier, $state)}
- )
- );
-}
-
-@mixin cdr-border-width-mixin($component, $key) {
- --cdr-#{$component}-border-width-default: var(
- --cdr-#{$component}-border-width,
- var(--cdr-space-inset-#{$key}, #{map.get($border-widths, $key)})
- );
-}
-
-@mixin cdr-border-style-mixin($component, $key) {
- --cdr-#{$component}-border-style-default: var(
- --cdr-#{$component}-border-style,
- var(--cdr-border-style-#{$key}, #{$key})
- );
-}
-
-@mixin cdr-border-mixin($component) {
- position: relative;
-
- &::after {
- border-radius: var(--cdr-#{$component}-radius-default);
- pointer-events: none;
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- content: '';
- border: var(--cdr-#{$component}-border-width-default)
- var(--cdr-#{$component}-border-style-default) var(--cdr-#{$component}-border-color-default);
- }
-}
-
-@mixin cdr-radius-mixin($component, $key) {
- --cdr-#{$component}-radius-default: var(
- --cdr-#{$component}-radius,
- var(--cdr-radius-#{$key}, #{map.get($radii, $key)})
- );
-
- border-radius: var(--cdr-#{$component}-radius-default);
- overflow: hidden;
-}
-
-@mixin cdr-shadow-mixin($component, $key) {
- box-shadow: var(
- --cdr-#{$component}-shadow,
- var(--cdr-prominence-#{$key}, #{map.get($shadows, $key)})
- );
-}
+@import './space.vars';
+@import './border.vars';
+@import './radius.vars';
+@import './shadow.vars';
+@import './background.vars';
diff --git a/src/styles/settings/radius.vars.scss b/src/styles/settings/radius.vars.scss
new file mode 100644
index 000000000..6bc2ca06a
--- /dev/null
+++ b/src/styles/settings/radius.vars.scss
@@ -0,0 +1,18 @@
+// Cedar token variable options
+$radii: (
+ 'sharp': $cdr-radius-sharp,
+ 'soft': $cdr-radius-soft,
+ 'softer': $cdr-radius-softer,
+ 'softest': $cdr-radius-softest,
+ 'round': $cdr-radius-round,
+);
+
+// Generates a radius property with a predictable format for overriding
+@mixin cdr-radius-mixin($component, $key) {
+ --cdr-#{$component}-radius-default: var(
+ --cdr-#{$component}-radius,
+ var(--cdr-radius-#{$key}, #{map.get($radii, $key)})
+ );
+ border-radius: var(--cdr-#{$component}-radius-default);
+ overflow: hidden;
+}
diff --git a/src/styles/settings/shadow.vars.scss b/src/styles/settings/shadow.vars.scss
new file mode 100644
index 000000000..aae1e56d7
--- /dev/null
+++ b/src/styles/settings/shadow.vars.scss
@@ -0,0 +1,16 @@
+// Available Cedar token shadow options
+$shadows: (
+ 'flat': $cdr-prominence-flat,
+ 'raised': $cdr-prominence-raised,
+ 'elevated': $cdr-prominence-elevated,
+ 'floating': $cdr-prominence-floating,
+ 'lifted': $cdr-prominence-lifted,
+);
+
+// Generates a shadow property with a predictable format for overriding
+@mixin cdr-shadow-mixin($component, $key) {
+ box-shadow: var(
+ --cdr-#{$component}-shadow,
+ var(--cdr-prominence-#{$key}, #{map.get($shadows, $key)})
+ );
+}
diff --git a/src/styles/settings/space.vars.scss b/src/styles/settings/space.vars.scss
new file mode 100644
index 000000000..b40be4c86
--- /dev/null
+++ b/src/styles/settings/space.vars.scss
@@ -0,0 +1,30 @@
+// All standard spacing options a component might use.
+// Intentially not including inset spacing to avoid duplicate looking options,
+// avoid possible confusion for users, and limit classes generated.
+$spacing: (
+ 'zero': $cdr-space-zero,
+ 'sixteenth-x': $cdr-space-sixteenth-x,
+ 'eighth-x': $cdr-space-eighth-x,
+ 'three-sixteenth-x': $cdr-space-three-sixteenth-x,
+ 'quarter-x': $cdr-space-quarter-x,
+ 'three-eighth-x': $cdr-space-three-eighth-x,
+ 'half-x': $cdr-space-half-x,
+ 'three-quarter-x': $cdr-space-three-quarter-x,
+ 'one-x': $cdr-space-one-x,
+ 'one-and-a-half-x': $cdr-space-one-and-a-half-x,
+ 'two-x': $cdr-space-two-x,
+ 'three-x': $cdr-space-three-x,
+ 'four-x': $cdr-space-four-x,
+ 'scale-0': 'var(--cdr-space-scale-0)',
+ 'scale-1': 'var(--cdr-space-scale-1)',
+ 'scale-2': 'var(--cdr-space-scale-2)',
+ 'scale-3': 'var(--cdr-space-scale-3)',
+ 'scale-4': 'var(--cdr-space-scale-4)',
+ 'scale-5': 'var(--cdr-space-scale-5)',
+ 'scale-6': 'var(--cdr-space-scale-6)',
+ 'scale-7': 'var(--cdr-space-scale-7)',
+ 'scale-8': 'var(--cdr-space-scale-8)',
+ 'scale-0--1': 'var(--cdr-space-scale-0--1)',
+ 'scale-3--4': 'var(--cdr-space-scale-3--4)',
+ 'scale-3--5': 'var(--cdr-space-scale-3--5)',
+);
diff --git a/src/types/interfaces.ts b/src/types/interfaces.ts
index cc7dbbc07..680aa0fd3 100644
--- a/src/types/interfaces.ts
+++ b/src/types/interfaces.ts
@@ -1,3 +1,4 @@
+import type { Component } from 'vue';
import type {
Tag,
Space,
@@ -7,11 +8,18 @@ import type {
BorderStyle,
Modifier,
Background,
- Orientation,
ScaleValue,
StatusType,
+ Flow,
+ StructureOption,
+ QueryType,
} from './other';
+/* eslint-disable @typescript-eslint/no-explicit-any */
+export interface NameValuePair {
+ [key: string]: any;
+}
+
/**
* HtmlAttributes data object for allowing any HTML attribute
* @interface HtmlAttributes
@@ -150,6 +158,60 @@ export interface baseTextProps extends HtmlAttributes {
tag?: string;
}
+/**
+ * Foundational container for creating structured layouts
+ * @interface Layout
+ * @extends HtmlAttributes
+ */
+export interface Layout extends HtmlAttributes {
+ /**
+ * Determines if the layout is in horizontal or vertical mode.
+ * @demoSelectMultiple false
+ * @values container, media
+ */
+ queryType?: QueryType;
+ /**
+ * Specifies the auto-placement behavior. This is translated to `grid-auto-flow`.
+ * @demoSelectMultiple false
+ * @values row, column
+ */
+ flow?: Flow;
+ /**
+ * Specifies how auto-generated tracks will be created. This is translated to either `grid-auto-columns` or `grid-auto-rows`, depending on flow.
+ */
+ flowValue?: string;
+ /**
+ * Determines the number of columns at various breakpoints
+ */
+ columns?: StructureOption;
+ /**
+ * Determines the number of rows at various breakpoints
+ */
+ rows?: StructureOption;
+ /**
+ * Specifies a gap based on the token options within Cedar.
+ * @demoSelectMultiple false
+ * @values zero, one-x, two-x, scale-4, scale-3--5
+ */
+ gap?: Space;
+ /**
+ * Specifies a row gap based on the token options within Cedar.
+ * @demoSelectMultiple false
+ * @values zero, one-x, two-x, scale-4, scale-3--5
+ */
+ rowGap?: Space;
+ /**
+ * Specifies a column gap based on the token options within Cedar.
+ * @demoSelectMultiple false
+ * @values zero, one-x, two-x, scale-4, scale-3--5
+ */
+ columnGap?: Space;
+ /**
+ * The component or HTML tag to render at the root level
+ */
+ as?: Component | string;
+}
+
/**
* surface contains the props used to create a surface
* @interface surface
@@ -175,7 +237,7 @@ export interface surface extends HtmlAttributes {
borderStyle?: BorderStyle;
/**
* Specifies a border width based on the token options within Cedar.
- * @values zero, sixteenth-x, eighth-x, three-sixteenth-x, quarter-x'
+ * @values zero, sixteenth-x, eighth-x, three-sixteenth-x, quarter-x
*/
borderWidth?: Space;
/**
@@ -226,11 +288,6 @@ export interface surfaceSelection extends HtmlAttributes {
* @values default
*/
modifier?: Modifier;
- /**
- * Determines if the layout is in horizontal or vertical mode.
- * @values horizontal, vertical
- */
- orientation?: Orientation;
/**
* Determines the role of the button. Typically, this will either be `radio` or `checkbox`.
*/
@@ -244,21 +301,13 @@ export interface surfaceSelection extends HtmlAttributes {
* Determines which HTML tag to use.
*/
tag?: Tag;
-}
-
-export interface surfaceSelectionLayout extends HtmlAttributes {
/**
- * Determines if the layout is in horizontal or vertical mode.
- * @values horizontal, vertical
+ * Layout props that will be merged with a set of defaults.
*/
- orientation?: Orientation;
+ layout?: Layout;
}
export interface fulfillmentTileContent extends HtmlAttributes {
- /**
- * Determines if the content should expand when space is available.
- */
- stretch?: boolean;
/**
* Sets the type scale
* @values -2, -1, 0, 1
@@ -273,3 +322,4 @@ export interface fulfillmentTileIcon extends HtmlAttributes {
*/
type?: StatusType;
}
+
diff --git a/src/types/other.ts b/src/types/other.ts
index b7efc4a91..6a9343a3d 100644
--- a/src/types/other.ts
+++ b/src/types/other.ts
@@ -25,12 +25,21 @@ export type SpaceFluid =
| 'scale-8';
export type SpaceScale = 'scale-0--1' | 'scale-3--4' | 'scale-3--5';
export type Space = SpaceFixed | SpaceFluid | SpaceScale;
+export type SpaceObject = { [key in Breakpoint]: Space };
+export type SpaceOption = Space | SpaceObject;
export type Shadow = 'flat' | 'raised' | 'elevated' | 'floating' | 'lifted';
export type Background = 'primary' | 'secondary' | 'brand-spruce' | 'sale';
export type Radius = 'sharp' | 'soft' | 'softer' | 'softest' | 'round';
export type BorderColor = 'primary' | 'secondary' | 'success' | 'warning' | 'error' | 'info';
export type BorderStyle = 'solid' | 'dotted' | 'dashed';
export type Modifier = 'default' | 'primary' | 'secondary';
-export type Orientation = 'vertical' | 'horizontal';
+export type Flow = 'row' | 'column';
+export type Structure = 'rows' | 'columns';
export type StatusType = 'info' | 'warning' | 'success' | 'error' | 'default';
export type ScaleValue = '-2' | '-1' | '0' | '1';
+export type Breakpoint = 'xs' | 'sm' | 'md' | 'lg';
+export type StructureValue = number | string;
+export type StructureArray = StructureValue[];
+export type StructureObject = { [key in Breakpoint]: StructureValue | StructureArray };
+export type StructureOption = StructureValue | StructureArray | StructureObject;
+export type QueryType = 'container' | 'media';
diff --git a/src/utils/layout.ts b/src/utils/layout.ts
new file mode 100644
index 000000000..c59f776a3
--- /dev/null
+++ b/src/utils/layout.ts
@@ -0,0 +1,83 @@
+import type { Breakpoint, Structure, StructureOption } from '../types/other';
+import type { NameValuePair, Layout } from '../types/interfaces';
+
+const breakpoints: Breakpoint[] = ['xs', 'sm', 'md', 'lg'];
+
+// Converts various columns or rows values to a map of inline CSS variables
+export function getStructureStyles({
+ props,
+ styles: newStyles = {},
+ structure,
+ breakpoint,
+}: {
+ props: Layout;
+ styles?: NameValuePair;
+ structure: Structure;
+ breakpoint?: Breakpoint;
+}) {
+ // This will be assigned a StructureOption.
+ // If breakpoint is passed then get the deep value, otherwise use top-level value.
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+ // @ts-ignore: Unreachable code error
+ const option: StructureOption = breakpoint ? props[structure][breakpoint] : props[structure];
+
+ if (!option) {
+ return newStyles;
+ }
+
+ const styles = { ...newStyles };
+
+ switch (true) {
+ // Example: "100px"
+ // Output:
+ // --cdr-layout-columns: 100px;
+ case typeof option === 'string': {
+ const breakpointPart = breakpoint ? `-${breakpoint}` : '';
+ styles[`--cdr-layout-${structure}${breakpointPart}`] = option;
+ break;
+ }
+ // Example: 2
+ // Output:
+ // --cdr-layout-columns: 1fr 1fr;
+ case typeof option === 'number': {
+ const breakpointPart = breakpoint ? `-${breakpoint}` : '';
+ styles[`--cdr-layout-${structure}${breakpointPart}`] = Array(option).fill('1fr').join(' ');
+ break;
+ }
+ // Example: ['100px', 1] => '100px 1fr'
+ // Output:
+ // --cdr-layout-columns: 2fr 1fr;
+ case Array.isArray(option): {
+ const breakpointPart = breakpoint ? `-${breakpoint}` : '';
+ styles[`--cdr-layout-${structure}${breakpointPart}`] = option
+ .map((option: any) => {
+ switch (typeof option) {
+ case 'number':
+ return `${option}fr`;
+ case 'string':
+ return option;
+ default:
+ return '';
+ }
+ })
+ .join(' ');
+ break;
+ }
+ // Example: {xs: 1, sm: ['100px', 1], md: ['200px', 1]}
+ // Output:
+ // --cdr-layout-columns-xs: 1fr;
+ // --cdr-layout-columns-sm: 100px 1fr;
+ // --cdr-layout-columns-md: 400px 1fr;
+ // --cdr-layout-columns-lg: 800px 1fr;
+ case typeof option === 'object': {
+ // Set values for breakpoints
+ breakpoints.forEach((bp) => {
+ const additionalStyles = getStructureStyles({ props, styles, structure, breakpoint: bp });
+ Object.assign(styles, additionalStyles);
+ });
+ break;
+ }
+ }
+
+ return styles;
+}
diff --git a/src/utils/surface.ts b/src/utils/surface.ts
index 7beaea848..5775ac0fc 100644
--- a/src/utils/surface.ts
+++ b/src/utils/surface.ts
@@ -1,4 +1,4 @@
-import type { surface, surfaceSelection, HtmlAttributes } from '../types/interfaces';
+import type { surface, surfaceSelection, HtmlAttributes, Layout } from '../types/interfaces';
// Manages the props passed along to all surfaces
export const getSurfaceProps = (props: surface, baseClass: string) => {
@@ -66,5 +66,19 @@ export const getSurfaceSelectionProps = (props: surfaceSelection, baseClass: str
additionalProps['data-loading'] = loading;
}
+ // Remove unwanted props that would be passed to element
+ delete additionalProps.layout;
+ delete additionalProps.modifier;
+ delete additionalProps.tag;
+
return { classes, ...additionalProps };
};
+
+export const getDefaultLayout = (defaults = {}) => {
+ const options: Layout = {
+ flow: 'column',
+ gap: 'three-eighth-x',
+ ...defaults,
+ };
+ return options;
+};
diff --git a/vite.pages.config.mts b/vite.pages.config.mts
new file mode 100644
index 000000000..2227f714b
--- /dev/null
+++ b/vite.pages.config.mts
@@ -0,0 +1,18 @@
+import { defineConfig } from 'vite';
+import vue from '@vitejs/plugin-vue';
+import config from './vite.config';
+
+export default defineConfig({
+ base: '/rei-cedar/',
+ css: config.css,
+ resolve: config.resolve,
+ plugins: [vue()],
+ define: { 'process.env': { NODE_ENV: 'production' } },
+ build: {
+ outDir: 'pages',
+ lib: {
+ name: 'main',
+ entry: './index.html',
+ },
+ },
+});