diff --git a/.prettierrc b/.prettierrc index 14301c6b..a865b461 100644 --- a/.prettierrc +++ b/.prettierrc @@ -5,5 +5,11 @@ "singleQuote": true, "trailingComma": "all", "bracketSpacing": true, - "plugins": ["prettier-plugin-organize-imports"] + "plugins": ["prettier-plugin-organize-imports"], + "overrides": [ + { + "files": ["**/*properties.css", "**/*tokens.css"], + "options": { "printWidth": 200 } + } + ] } diff --git a/.storybook/preview.ts b/.storybook/preview.ts index b8971978..486b070a 100644 --- a/.storybook/preview.ts +++ b/.storybook/preview.ts @@ -1,5 +1,7 @@ import type { Preview } from '@storybook/vue3-vite' import { AppCompose, Wrapper, type YTheme } from '../src' +// Supports weights 100-900 +import '@fontsource-variable/roboto' const theme: YTheme = { primary: '#e3c567', @@ -27,9 +29,9 @@ const preview: Preview = { components: { story, AppCompose, Wrapper }, template: ` - + - + `, diff --git a/_templates/component/new/component.css.ejs.t b/_templates/new/component/component.css.ejs.t similarity index 100% rename from _templates/component/new/component.css.ejs.t rename to _templates/new/component/component.css.ejs.t diff --git a/_templates/component/new/component.stories.ts.t b/_templates/new/component/component.stories.ts.t similarity index 100% rename from _templates/component/new/component.stories.ts.t rename to _templates/new/component/component.stories.ts.t diff --git a/_templates/component/new/component.test.ejs.t b/_templates/new/component/component.test.ejs.t similarity index 100% rename from _templates/component/new/component.test.ejs.t rename to _templates/new/component/component.test.ejs.t diff --git a/_templates/component/new/component.vue.t b/_templates/new/component/component.vue.t similarity index 100% rename from _templates/component/new/component.vue.t rename to _templates/new/component/component.vue.t diff --git a/_templates/component/new/index.ts.t b/_templates/new/component/index.ts.t similarity index 100% rename from _templates/component/new/index.ts.t rename to _templates/new/component/index.ts.t diff --git a/_templates/component/new/prompt.js b/_templates/new/component/prompt.js similarity index 100% rename from _templates/component/new/prompt.js rename to _templates/new/component/prompt.js diff --git a/bin/templates/compose-theme-goal.css b/bin/templates/compose-theme-goal.css index c08aa998..bb50fb60 100644 --- a/bin/templates/compose-theme-goal.css +++ b/bin/templates/compose-theme-goal.css @@ -8,35 +8,60 @@ /** * ZINDEX */ + /** * TYPOGRAPHY */ + /** * BREAKPOINT */ + /** * SPACE */ + /* --zIndex-undefined: 1000; */ + /* --typography-text: clamp(0.4444rem, 0.6881rem - 0.2407vw, 0.64rem); */ + /* --typography-text: clamp(0.6667rem, 0.8328rem - 0.1641vw, 0.8rem); */ + /* --typography-text: clamp(1rem, 1rem + 0vw, 1rem); */ + /* --typography-text: clamp(1.25rem, 1.1885rem + 0.3077vw, 1.5rem); */ + /* --typography-text: clamp(1.5625rem, 1.3933rem + 0.8462vw, 2.25rem); */ + /* --typography-text: clamp(1.9531rem, 1.6031rem + 1.75vw, 3.375rem); */ + /* --typography-text: clamp(2.4414rem, 1.7962rem + 3.226vi, 5.0625rem); */ + /* --typography-heading: calc(1rem * 2.5); */ + /* --breakpoint-mobile: 640px; */ + /* --breakpoint-tablet: 768px; */ + /* --breakpoint-desktop: 1024px; */ + /* --breakpoint-desktop-xl: 1280px; */ + /* --breakpoint-desktop-xxl: 1820px; */ + /* --space-unit: 1rem; */ + /* --space-xxs: calc(0.25 * var(--space-unit)); */ + /* --space-xs: calc(0.5 * var(--space-unit)); */ + /* --space-sm: calc(0.75 * var(--space-unit)); */ + /* --space-md: calc(1 * var(--space-unit)); */ + /* --space-lg: calc(1.5 * var(--space-unit)); */ + /* --space-xl: calc(2 * var(--space-unit)); */ + /* --space-xxl: calc(4 * var(--space-unit)); */ } diff --git a/bin/templates/compose-theme.css b/bin/templates/compose-theme.css index 99384cd7..c4b5c9f9 100644 --- a/bin/templates/compose-theme.css +++ b/bin/templates/compose-theme.css @@ -6,7 +6,9 @@ */ :root { /* -------------------------------------------------- */ + /* Breakpoints */ + /* -------------------------------------------------- */ --breakpoints-mobile: 640px; --breakpoints-tablet: 768px; @@ -15,12 +17,16 @@ --breakpoints-desktop-xxl: 1820px; /* -------------------------------------------------- */ + /* Layout */ + /* -------------------------------------------------- */ --layout-zIndex: 1000; /* -------------------------------------------------- */ + /* Space */ + /* -------------------------------------------------- */ --space-unit: 1rem; --space-xxs: calc(0.25 * var(--space-unit)); @@ -32,12 +38,16 @@ --space-xxl: calc(4 * var(--space-unit)); /* -------------------------------------------------- */ + /* Font */ + /* -------------------------------------------------- */ --font-gotham: assets/fonts/gotham/gotham.woff2; /* -------------------------------------------------- */ + /* Text */ + /* -------------------------------------------------- */ --text-xs: clamp(0.4444rem, 0.6881rem - 0.2407vw, 0.64rem); --text-sm: clamp(0.6667rem, 0.8328rem - 0.1641vw, 0.8rem); @@ -48,7 +58,9 @@ --text-h1: clamp(2.4414rem, 1.7962rem + 3.226vi, 5.0625rem); /* -------------------------------------------------- */ + /* Heading */ + /* -------------------------------------------------- */ --heading-height: calc(1rem * 2.5); } diff --git a/eslint.config.mjs b/eslint.config.mjs index cbfe6258..ed8e0727 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -30,9 +30,9 @@ export default defineConfig([ 'vue/component-name-in-template-casing': [ 'warn', 'PascalCase', - { - registeredComponentsOnly: false, - }, + // { + // registeredComponentsOnly: false, + // }, ], '@typescript-eslint/no-empty-object-type': 'off', }, diff --git a/package-lock.json b/package-lock.json index 877a5f2c..87191523 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "@use-compose/ui", "version": "0.4.0", "dependencies": { + "@fontsource-variable/roboto": "^5.2.9", "compression": "1.8.1", "culori": "4.0.1", "express": "5.1.0", @@ -47,7 +48,6 @@ "lint-staged": "16.1.0", "prettier": "3.5.3", "prettier-plugin-organize-imports": "4.1.0", - "react-dom": "19.2.0", "sass": "1.89.2", "storybook": "10.1.11", "storybook-addon-pseudo-states": "10.1.11", @@ -64,6 +64,7 @@ "vite-plugin-dts": "4.5.4", "vite-plugin-linter": "2.1.1", "vite-plugin-vue-devtools": "8.0.5", + "vite-tsconfig-paths": "6.0.4", "vitest": "4.0.17", "vue-tsc": "2.2.10" } @@ -1884,6 +1885,15 @@ "react": "^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, + "node_modules/@fontsource-variable/roboto": { + "version": "5.2.9", + "resolved": "https://registry.npmjs.org/@fontsource-variable/roboto/-/roboto-5.2.9.tgz", + "integrity": "sha512-uH58g1An9Z4Efiviu0YuN8lvYf22TXidCx2++ZPpEegviaPaYQUwNbQZyr5lO2ae3pM07AolUabngLrlYtuzfA==", + "license": "OFL-1.1", + "funding": { + "url": "https://github.com/sponsors/ayuhito" + } + }, "node_modules/@hapi/hoek": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", @@ -10024,6 +10034,13 @@ "dev": true, "license": "MIT" }, + "node_modules/globrex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz", + "integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg==", + "dev": true, + "license": "MIT" + }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", @@ -17968,6 +17985,27 @@ "dev": true, "license": "MIT" }, + "node_modules/tsconfck": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/tsconfck/-/tsconfck-3.1.6.tgz", + "integrity": "sha512-ks6Vjr/jEw0P1gmOVwutM3B7fWxoWBL2KRDb1JfqGVawBmO5UsvmWOQFGHBPl5yxYz4eERr19E6L7NMv+Fej4w==", + "dev": true, + "license": "MIT", + "bin": { + "tsconfck": "bin/tsconfck.js" + }, + "engines": { + "node": "^18 || >=20" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", @@ -18888,6 +18926,27 @@ "vite": "^3.0.0-0 || ^4.0.0-0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0" } }, + "node_modules/vite-tsconfig-paths": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/vite-tsconfig-paths/-/vite-tsconfig-paths-6.0.4.tgz", + "integrity": "sha512-iIsEJ+ek5KqRTK17pmxtgIxXtqr3qDdE6OxrP9mVeGhVDNXRJTKN/l9oMbujTQNzMLe6XZ8qmpztfbkPu2TiFQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.1", + "globrex": "^0.1.2", + "tsconfck": "^3.0.3", + "vite": "*" + }, + "peerDependencies": { + "vite": "*" + }, + "peerDependenciesMeta": { + "vite": { + "optional": true + } + } + }, "node_modules/vite/node_modules/fdir": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", diff --git a/package.json b/package.json index 2ca21ade..0a6404cf 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "build:server": "vite build --outDir dist/server --ssr src/entry-server.js", "build:style": "style-dictionary build --config style-dictionary/config.js ", "chromatic": "chromatic --exit-zero-on-changes", - "component:new": "npx hygen component new", + "new:component": "npx hygen new component", "dev": "vite", "dev:ssr": "node server", "format": "prettier --write . --config ./.prettierrc", @@ -32,6 +32,7 @@ "test": "vitest" }, "dependencies": { + "@fontsource-variable/roboto": "^5.2.9", "compression": "1.8.1", "culori": "4.0.1", "express": "5.1.0", @@ -68,7 +69,6 @@ "lint-staged": "16.1.0", "prettier": "3.5.3", "prettier-plugin-organize-imports": "4.1.0", - "react-dom": "19.2.0", "sass": "1.89.2", "storybook": "10.1.11", "storybook-addon-pseudo-states": "10.1.11", @@ -85,6 +85,7 @@ "vite-plugin-dts": "4.5.4", "vite-plugin-linter": "2.1.1", "vite-plugin-vue-devtools": "8.0.5", + "vite-tsconfig-paths": "6.0.4", "vitest": "4.0.17", "vue-tsc": "2.2.10" }, diff --git a/src/assets/css/base/fonts.css b/src/assets/css/base/fonts.css index cd530a37..d18923b8 100644 --- a/src/assets/css/base/fonts.css +++ b/src/assets/css/base/fonts.css @@ -3,7 +3,9 @@ @font-face { font-family: gotham; src: url('../fonts/GOTHAM-BOOK.OTF') format('opentype'); + /* src: var(--_font-regular); */ + /* src: url('/fonts/GOTHAM-BOOK.OTF') format('opentype'); */ font-display: swap; } @@ -11,6 +13,7 @@ @font-face { font-family: gotham; src: url('../fonts/GOTHAM-BOLD.OTF') format('opentype'); + /* src: var(--_font-bold); */ font-weight: 700; font-display: swap; @@ -18,7 +21,9 @@ @font-face { font-family: gotham; + /* src: url('../fonts/GOTHAM-BLACKITALIC.OTF') format('opentype'); */ + /* src: var(--_font-bolder); */ src: url('../fonts/GOTHAM-BLACKITALIC.OTF') format('opentype'); font-weight: 900; @@ -29,13 +34,15 @@ @font-face { font-family: gotham; src: url('../fonts/GOTHAM-BLACK.OTF') format('opentype'); + /* src: var(--_font-bolder-italic); */ font-weight: 900; font-display: swap; } body { - font-family: 'Roboto Slab', serif; + font-family: 'Roboto Variable', sans-serif; + /* font-family: gotham; */ } diff --git a/src/assets/css/base/reset.css b/src/assets/css/base/reset.css new file mode 100644 index 00000000..61619aac --- /dev/null +++ b/src/assets/css/base/reset.css @@ -0,0 +1,71 @@ +/* + Josh's Custom CSS Reset + https://www.joshwcomeau.com/css/custom-css-reset/ +*/ + +*, +*::before, +*::after { + box-sizing: border-box; +} + +* { + margin: 0; +} + +body { + line-height: 1.5; + -webkit-font-smoothing: antialiased; +} + +img, +picture, +video, +canvas, +svg { + display: block; + max-width: 100%; +} + +input, +button, +textarea, +select { + font: inherit; +} + +p, +h1, +h2, +h3, +h4, +h5, +h6 { + overflow-wrap: break-word; +} + +p { + text-wrap: pretty; +} + +h1, +h2, +h3, +h4, +h5, +h6 { + text-wrap: balance; +} + +#root, +#__next { + isolation: isolate; +} + +/* CUSTOM */ +ul, +ol { + list-style-type: none; + padding: 0; + margin: 0; +} diff --git a/src/assets/css/global.css b/src/assets/css/global.css index 4b1ed3fe..7b52fd0a 100644 --- a/src/assets/css/global.css +++ b/src/assets/css/global.css @@ -1,13 +1,27 @@ @import './base/conditional.css'; + /* @import './base/variants.css'; */ @import './base/component/component.css'; @import './base/fonts.css'; + +/* TODO: */ + +/* @import './base/reset.css'; */ + /* @import './base/variables.css'; */ @import './utils/animations.css'; @import './components/common.css'; @import './components/table.css'; + /* @import './themes/private-theme.css'; */ + /* @import './themes/public-theme.css'; */ +@import './layout/container.css'; +@import './layout/cluster.css'; +@import './layout/switcher.css'; +@import './layout/wrapper.css'; +@import './utils/media.css'; +@import './themes/core.css'; @import './theme.css'; @import './themes/compose-ui/compose-ui-base.css'; @import './themes/compose-ui/compose-ui.state.css'; diff --git a/src/assets/css/layout/cluster.css b/src/assets/css/layout/cluster.css new file mode 100644 index 00000000..9c2acb90 --- /dev/null +++ b/src/assets/css/layout/cluster.css @@ -0,0 +1,12 @@ +/* + Cluster Layout + ----------------------------- + A layout for grouping items together with consistent spacing. +*/ +.cluster { + display: flex; + flex-wrap: wrap; + gap: var(--_cluster-gap); + align-items: center; + justify-content: flex-start; +} diff --git a/src/assets/css/layout/container.css b/src/assets/css/layout/container.css new file mode 100644 index 00000000..1b24bff2 --- /dev/null +++ b/src/assets/css/layout/container.css @@ -0,0 +1,6 @@ +/* https://grafikart.fr/tutoriels/conteneur-css-1233 */ +.container { + box-sizing: border-box; + width: min(var(--breakpoint-sm), calc(100% - 4 * var(--layout-mobile-padding))); + margin-inline: auto; +} diff --git a/src/assets/css/layout/switcher.css b/src/assets/css/layout/switcher.css new file mode 100644 index 00000000..b06dba11 --- /dev/null +++ b/src/assets/css/layout/switcher.css @@ -0,0 +1,21 @@ +/** + * Holy Albatross utility / composition for switcher + * https://heydonworks.com/article/the-flexbox-holy-albatross-reincarnated/ + */ +.switcher, +.holy { + display: flex; + flex-wrap: wrap; + gap: var(--_switcher-gap, 1rem); + + --switch: var(--_switcher-modifier); +} + +.switcher > *, +.holy > * { + flex-grow: 1; + flex-basis: calc((var(--switch) - 100%) * 999); + + /* avoid overflow from long content */ + min-width: 0; +} diff --git a/src/assets/css/layout/wrapper.css b/src/assets/css/layout/wrapper.css new file mode 100644 index 00000000..9c7ca58f --- /dev/null +++ b/src/assets/css/layout/wrapper.css @@ -0,0 +1,36 @@ +/* TODO: */ + +/* .wrapper { */ + +/* https://grafikart.fr/tutoriels/conteneur-css-1233 */ + +/* box-sizing: border-box; + width: min( + var(--breakpoint-desktop-xl), + calc(100% - 2 * var(--layout-mobile-padding)) + ); + margin-inline: auto; +} */ + +/* https://css-tricks.com/use-css-clamp-to-create-a-more-flexible-wrapper-utility/ */ +.wrapper { + /* width: clamp(100%, 90vw, 70rem); */ + width: 100%; + + /* https://www.oceg.org/ */ + + /* max-width: clamp(16rem, var(--wrapper-max-width, 98rem), 95vw); */ + + /* TODO: */ + max-width: clamp(16rem, var(--wrapper-max-width, 80rem), 95vw); + margin-left: auto; + margin-right: auto; + padding-left: var(--layout-space-unit); + padding-right: var(--layout-space-unit); +} + +@media screen and (width >= 48rem) { + .wrapper { + --wrapper-max-width: var(--breakpoint-md); + } +} diff --git a/src/assets/css/theme.TODO/state.css b/src/assets/css/theme.TODO/state.css index 2b923603..437734e0 100644 --- a/src/assets/css/theme.TODO/state.css +++ b/src/assets/css/theme.TODO/state.css @@ -13,26 +13,36 @@ @property --state { syntax: "base | hover | active | focus | disabled"; initial-value: base; inherits: true; } /* token-or-0 */ + /* prettier-ignore */ @property --_state-base-else-0 { syntax: "base | "; initial-value: 0; inherits: true; } + /* prettier-ignore */ @property --_state-hover-else-0 { syntax: "hover | "; initial-value: 0; inherits: true; } + /* prettier-ignore */ @property --_state-active-else-0 { syntax: "active | "; initial-value: 0; inherits: true; } + /* prettier-ignore */ @property --_state-focus-else-0 { syntax: "focus | "; initial-value: 0; inherits: true; } + /* prettier-ignore */ @property --_state-disabled-else-0 { syntax: "disabled | "; initial-value: 0; inherits: true; } /* bits */ + /* prettier-ignore */ @property --is-state-base { syntax: ""; initial-value: 1; inherits: true; } + /* prettier-ignore */ @property --is-state-hover { syntax: ""; initial-value: 1; inherits: true; } + /* prettier-ignore */ @property --is-state-active { syntax: ""; initial-value: 1; inherits: true; } + /* prettier-ignore */ @property --is-state-focus { syntax: ""; initial-value: 1; inherits: true; } + /* prettier-ignore */ @property --is-state-disabled { syntax: ""; initial-value: 1; inherits: true; } } @@ -46,10 +56,8 @@ * Only apply to the component root, otherwise everything on the page can inherit it. */ - [data-compose-ui]:not([disabled]):not(.disabled):not(:hover):not(:active):not(:focus):not( - :focus-visible - ), - [data-compose-ui].base:not([disabled]):not(.disabled) { + [data-compose-ui]:not([disabled], .disabled, :hover, :active, :focus, :focus-visible), + [data-compose-ui].base:not([disabled], .disabled) { --state: base; } @@ -83,12 +91,15 @@ [data-compose-ui]:has(:hover, .hover) { --state: hover; } + [data-compose-ui]:has(:active, .active) { --state: active; } + [data-compose-ui]:has(:focus-visible, :focus, .focus-visible, .focus) { --state: focus; } + [data-compose-ui]:has(.disabled, :disabled, [disabled]) { --state: disabled; } @@ -104,16 +115,12 @@ */ --_state-base-else-0: var(--state); --is-state-base: var(--_state-base-else-0); - --_state-hover-else-0: var(--state); --is-state-hover: var(--_state-hover-else-0); - --_state-active-else-0: var(--state); --is-state-active: var(--_state-active-else-0); - --_state-focus-else-0: var(--state); --is-state-focus: var(--_state-focus-else-0); - --_state-disabled-else-0: var(--state); --is-state-disabled: var(--_state-disabled-else-0); diff --git a/src/assets/css/theme.TODO/tone.css b/src/assets/css/theme.TODO/tone.css index 01c20e54..f894f944 100644 --- a/src/assets/css/theme.TODO/tone.css +++ b/src/assets/css/theme.TODO/tone.css @@ -9,30 +9,42 @@ @property --tone { syntax: "primary | secondary | danger | background | accent | neutral"; initial-value: primary; inherits: true; } /* token-or-0 (else-0) */ + /* prettier-ignore */ @property --_tone-primary-else-0 { syntax: "primary | "; initial-value: 0; inherits: true; } + /* prettier-ignore */ @property --_tone-secondary-else-0 { syntax: "secondary | "; initial-value: 0; inherits: true; } + /* prettier-ignore */ @property --_tone-danger-else-0 { syntax: "danger | "; initial-value: 0; inherits: true; } + /* prettier-ignore */ @property --_tone-background-else-0 { syntax: "background | "; initial-value: 0; inherits: true; } + /* prettier-ignore */ @property --_tone-accent-else-0 { syntax: "accent | "; initial-value: 0; inherits: true; } + /* prettier-ignore */ @property --_tone-neutral-else-0 { syntax: "neutral | "; initial-value: 0; inherits: true; } /* bits (invalid => initial-value 1) */ + /* prettier-ignore */ @property --is-tone-primary { syntax: ""; initial-value: 1; inherits: true; } + /* prettier-ignore */ @property --is-tone-secondary { syntax: ""; initial-value: 1; inherits: true; } + /* prettier-ignore */ @property --is-tone-danger { syntax: ""; initial-value: 1; inherits: true; } + /* prettier-ignore */ @property --is-tone-background { syntax: ""; initial-value: 1; inherits: true; } + /* prettier-ignore */ @property --is-tone-accent { syntax: ""; initial-value: 1; inherits: true; } + /* prettier-ignore */ @property --is-tone-neutral { syntax: ""; initial-value: 1; inherits: true; } } @@ -78,19 +90,14 @@ */ --_tone-primary-else-0: var(--tone); --is-tone-primary: var(--_tone-primary-else-0); - --_tone-secondary-else-0: var(--tone); --is-tone-secondary: var(--_tone-secondary-else-0); - --_tone-danger-else-0: var(--tone); --is-tone-danger: var(--_tone-danger-else-0); - --_tone-background-else-0: var(--tone); --is-tone-background: var(--_tone-background-else-0); - --_tone-accent-else-0: var(--tone); --is-tone-accent: var(--_tone-accent-else-0); - --_tone-neutral-else-0: var(--tone); --is-tone-neutral: var(--_tone-neutral-else-0); diff --git a/src/assets/css/theme.TODO/variant.css b/src/assets/css/theme.TODO/variant.css index 66492b23..5ac1f7bb 100644 --- a/src/assets/css/theme.TODO/variant.css +++ b/src/assets/css/theme.TODO/variant.css @@ -9,22 +9,29 @@ @property --variant { syntax: "contained | outlined | text"; initial-value: contained; inherits: true; } /* token-or-0 */ + /* prettier-ignore */ @property --_variant-contained-else-0 { syntax: "contained | "; initial-value: 0; inherits: true; } + /* prettier-ignore */ @property --_variant-outlined-else-0 { syntax: "outlined | "; initial-value: 0; inherits: true; } + /* prettier-ignore */ @property --_variant-text-else-0 { syntax: "text | "; initial-value: 0; inherits: true; } /* bits */ + /* prettier-ignore */ @property --is-variant-contained { syntax: ""; initial-value: 1; inherits: true; } + /* prettier-ignore */ @property --is-variant-outlined { syntax: ""; initial-value: 1; inherits: true; } + /* prettier-ignore */ @property --is-variant-text { syntax: ""; initial-value: 1; inherits: true; } /* optional numeric feature flags derived from variant */ + /* prettier-ignore */ @property --has-border { syntax: ""; initial-value: 0; inherits: true; } } @@ -56,10 +63,8 @@ */ --_variant-contained-else-0: var(--variant); --is-variant-contained: var(--_variant-contained-else-0); - --_variant-outlined-else-0: var(--variant); --is-variant-outlined: var(--_variant-outlined-else-0); - --_variant-text-else-0: var(--variant); --is-variant-text: var(--_variant-text-else-0); @@ -192,8 +197,10 @@ --component-border-width-effective: calc( var(--has-border) * var(--component-border-width, 0px) ); + border-width: var(--component-border-width-effective); border-style: var(--component-border-style, solid); + /* border-color can stay computed later (you already do border-color: oklch(...)) */ } } diff --git a/src/assets/css/theme.css b/src/assets/css/theme.css index 0a8fc91f..156fe795 100644 --- a/src/assets/css/theme.css +++ b/src/assets/css/theme.css @@ -2,12 +2,13 @@ syntax: ''; inherits: true; } */ -@import url('./tokens/css/variants.css') layer(theme-api); +@import './themes/tokens/css/variants.css' layer(theme-api); /* * CSS Type Grinding - https://www.bitovi.com/blog/css-only-type-grinding-casting-tokens-into-useful-values */ -@layer state; + +/* @layer state; */ /* * Color Properties @@ -110,7 +111,6 @@ --primary: var(--primary-else-0); --secondary-else-0: var(--color); --secondary: var(--secondary-else-0); - --base-else-0: var(--state); --base: var(--base-else-0); --hover-else-0: var(--state); @@ -186,11 +186,10 @@ .outlined { --component-color-border: var(--theme-current-color); + /* --component-color-text: var(--theme-current-color); */ --component-border-width: 2px; - --border: yes; - --variant: outlined; --border: yes; } @@ -208,6 +207,7 @@ --outlined: var(--outlined-else-0); --text-else-0: var(--variant); --text: var(--text-else-0); + border-width: calc(var(--has-border) * var(--component-border-width)); border-style: calc(var(--has-border) * var(--component-border-style)); border: var(--component-border-width) var(--component-border-style) var(--component-color-border); @@ -226,17 +226,14 @@ --v-bg-c: var(--variant-contained-bg-chroma); --v-bg-h: var(--variant-contained-bg-hue); --v-bg-a: var(--variant-contained-bg-opacity); - --v-border-l: var(--variant-contained-border-lightness); --v-border-c: var(--variant-contained-border-chroma); --v-border-h: var(--variant-contained-border-hue); --v-border-a: var(--variant-contained-border-opacity); - --v-text-l: var(--variant-contained-text-lightness); --v-text-c: var(--variant-contained-text-chroma); --v-text-h: var(--variant-contained-text-hue); --v-text-a: var(--variant-contained-text-opacity); - --component-text-color: white; } @@ -245,12 +242,10 @@ --v-bg-c: var(--variant-outlined-bg-chroma); --v-bg-h: var(--variant-outlined-bg-hue); --v-bg-a: var(--variant-outlined-bg-opacity); - --v-border-l: var(--variant-outlined-border-lightness); --v-border-c: var(--variant-outlined-border-chroma); --v-border-h: var(--variant-outlined-border-hue); --v-border-a: var(--variant-outlined-border-opacity); - --v-text-l: var(--variant-outlined-text-lightness); --v-text-c: var(--variant-outlined-text-chroma); --v-text-h: var(--variant-outlined-text-hue); @@ -262,17 +257,16 @@ --v-bg-c: var(--variant-text-bg-chroma); --v-bg-h: var(--variant-text-bg-hue); --v-bg-a: var(--variant-text-bg-opacity); - --v-border-l: var(--variant-text-border-lightness); --v-border-c: var(--variant-text-border-chroma); --v-border-h: var(--variant-text-border-hue); --v-border-a: var(--variant-text-border-opacity); - --v-text-l: var(--variant-text-text-lightness); --v-text-c: var(--variant-text-text-chroma); --v-text-h: var(--variant-text-text-hue); --v-text-a: var(--variant-text-text-opacity); } + /* same for variant-text */ /* @@ -378,17 +372,14 @@ } [data-compose-ui].base { - /* base default */ --s-bg-l: var(--state-base-bg-lightness); --s-bg-c: var(--state-base-bg-chroma); --s-bg-h: var(--state-base-bg-hue); --s-bg-a: var(--state-base-bg-opacity); - --s-border-l: var(--state-base-border-lightness); --s-border-c: var(--state-base-border-chroma); --s-border-h: var(--state-base-border-hue); --s-border-a: var(--state-base-border-opacity); - --s-text-l: var(--state-base-text-lightness); --s-text-c: var(--state-base-text-chroma); --s-text-h: var(--state-base-text-hue); @@ -397,17 +388,14 @@ [data-compose-ui]:hover, [data-compose-ui].hover { - /* hover */ --s-bg-l: var(--state-hover-bg-lightness); --s-bg-c: var(--state-hover-bg-chroma); --s-bg-h: var(--state-hover-bg-hue); --s-bg-a: var(--state-hover-bg-opacity); - --s-border-l: var(--state-hover-border-lightness); --s-border-c: var(--state-hover-border-chroma); --s-border-h: var(--state-hover-border-hue); --s-border-a: var(--state-hover-border-opacity); - --s-text-l: var(--state-hover-text-lightness); --s-text-c: var(--state-hover-text-chroma); --s-text-h: var(--state-hover-text-hue); @@ -416,17 +404,14 @@ [data-compose-ui]:active, [data-compose-ui].active { - /* active */ --s-bg-l: var(--state-active-bg-lightness); --s-bg-c: var(--state-active-bg-chroma); --s-bg-h: var(--state-active-bg-hue); --s-bg-a: var(--state-active-bg-opacity); - --s-border-l: var(--state-active-border-lightness); --s-border-c: var(--state-active-border-chroma); --s-border-h: var(--state-active-border-hue); --s-border-a: var(--state-active-border-opacity); - --s-text-l: var(--state-active-text-lightness); --s-text-c: var(--state-active-text-chroma); --s-text-h: var(--state-active-text-hue); @@ -437,17 +422,14 @@ [data-compose-ui]:focus-visible, [data-compose-ui].focus-visible, [data-compose-ui].focus { - /* focus */ --s-bg-l: var(--state-focus-bg-lightness); --s-bg-c: var(--state-focus-bg-chroma); --s-bg-h: var(--state-focus-bg-hue); --s-bg-a: var(--state-focus-bg-opacity); - --s-border-l: var(--state-focus-border-lightness); --s-border-c: var(--state-focus-border-chroma); --s-border-h: var(--state-focus-border-hue); --s-border-a: var(--state-focus-border-opacity); - --s-text-l: var(--state-focus-text-lightness); --s-text-c: var(--state-focus-text-chroma); --s-text-h: var(--state-focus-text-hue); @@ -457,17 +439,14 @@ [data-compose-ui]:disabled, [data-compose-ui].disabled, [data-compose-ui][disabled] { - /* disabled */ --s-bg-l: var(--state-disabled-bg-lightness); --s-bg-c: var(--state-disabled-bg-chroma); --s-bg-h: var(--state-disabled-bg-hue); --s-bg-a: var(--state-disabled-bg-opacity); - --s-border-l: var(--state-disabled-border-lightness); --s-border-c: var(--state-disabled-border-chroma); --s-border-h: var(--state-disabled-border-hue); --s-border-a: var(--state-disabled-border-opacity); - --s-text-l: var(--state-disabled-text-lightness); --s-text-c: var(--state-disabled-text-chroma); --s-text-h: var(--state-disabled-text-hue); @@ -533,8 +512,8 @@ .y-select { /* Base for all theming: if --unstyled is set, all styles are removed */ --styled: calc(1 - var(--unstyled)); - --is-box-shadow-hidden: calc(1 - var(--raw, 0)); + /* --component-box-shadow-hover: var(--component-box-shadow-x) var(--component-box-shadow-y) 0 0 var(--component-box-shadow-color); */ --component-box-shadow-color: calc( @@ -548,6 +527,13 @@ calc(var(--active) * 100% + var(--focus) * 100% + var(--disabled) * 100%) ); --shadow-dark: var(--color-main-dark); + + /* --component-shadow-depth: calc( + var(--is-state-base) * var(--_component-shadow-base) + var(--is-state-hover) * + var(--_component-shadow-hover) + var(--is-state-active) * var(--_component-shadow-active) + + var(--is-state-focus) * var(--_component-shadow-focus) + var(--is-state-disabled) * + var(--_component-shadow-disabled) - 1 * var(--_component-transform-depth) + ); */ --component-shadow-depth: calc( var(--base) * var(--_component-shadow-base) + var(--hover) * var(--_component-shadow-hover) + var(--active) * var(--_component-shadow-active) + var(--focus) * @@ -564,6 +550,13 @@ /** * Component Transform */ + + /* --_component-transform-depth: calc( + var(--_component-transform-base) * var(--is-state-base) + var(--_component-transform-hover) * + var(--is-state-hover) + var(--_component-transform-active) * var(--is-state-active) + + var(--_component-transform-focus) * var(--is-state-focus) + + var(--_component-transform-disabled) * var(--is-state-disabled) + ); */ --_component-transform-depth: calc( var(--_component-transform-base) * var(--base) + var(--_component-transform-hover) * var(--hover) + var(--_component-transform-active) * var(--active) + @@ -571,12 +564,14 @@ var(--disabled) ); --transform-depth: calc(var(--_component-transform-depth) * var(--_layout-depth-base)); + /* --transform-depth: var(--_component-transform-depth); */ --component-transform: translate(var(--transform-depth), var(--transform-depth)); --component-box-shadow: var(--component-box-shadow-x) var(--component-box-shadow-y) 0 0 var(--component-box-shadow-color); --component-box-shadow-base: calc(var(--component-box-shadow-x)) calc(var(--component-box-shadow-y)) 0 0 black; + /* --component-box-shadow-hover: var(--component-box-shadow-x) var(--component-box-shadow-y) 0 0 var(--shadow-dark); */ @@ -588,17 +583,14 @@ --bg-c: calc(var(--tone-c) + var(--v-bg-c) + var(--s-bg-c)); --bg-h: calc(var(--tone-h) + var(--v-bg-h) + var(--s-bg-h)); --bg-a: calc(var(--tone-a) * var(--v-bg-a) * var(--s-bg-a)); - --border-l: calc(var(--tone-l) + var(--v-border-l) + var(--s-border-l)); --border-c: calc(var(--tone-c) + var(--v-border-c) + var(--s-border-c)); --border-h: calc(var(--tone-h) + var(--v-border-h) + var(--s-border-h)); --border-a: calc(var(--tone-a) * var(--v-border-a) * var(--s-border-a)); - --text-l: calc(var(--tone-l) + var(--v-text-l) + var(--s-text-l)); --text-c: calc(var(--tone-c) + var(--v-text-c) + var(--s-text-c)); --text-h: calc(var(--tone-h) + var(--v-text-h) + var(--s-text-h)); --text-a: calc(var(--tone-a) * var(--v-text-a) * var(--s-text-a)); - --component-bg-color: oklch(var(--bg-l) var(--bg-c) var(--bg-h) / var(--bg-a)); --component-border-color: oklch( var(--border-l) var(--border-c) var(--border-h) / var(--border-a) @@ -607,7 +599,6 @@ /* border: var(--component-border-width) var(--component-border-style) var(--component-border-color); */ border-color: var(--component-color-border); - background-color: var(--component-bg-color); color: var(--component-text-color); @@ -616,6 +607,7 @@ --component-translate-x: var(--theme-base-unit-calc); --component-translate-y: var(--theme-base-unit-calc); */ + /* --box-shadow-base: var(--box-shadow-x) var(--box-shadow-y) 0 0 black; --box-shadow-hover: var(--box-shadow-x) var(--box-shadow-y) 0 0 var(--theme-current-color); */ @@ -624,6 +616,7 @@ * Pseudo-boolean CSS custom properties - https://keithclark.co.uk/articles/pseudo-boolean-css-custom-properties * Define colors based on component state */ + /* --component-color: color-mix( in srgb, var(--font-color) calc(100% * var(--primary, 0)), @@ -643,12 +636,15 @@ ); */ /* --component-box-shadow: var(--box-shadow-base); */ + /* --component-padding-x: calc(var(--layout-space-unit) * var(--styled)); */ + /* --component-padding-y: 0; */ --component-border-style: solid; /* --component-transform: translate(var(--component-translate-x), var(--component-translate-y)); */ } + /* [data-compose-ui] { --component-bg-hue: calc(var(--color-bg-hue)); diff --git a/src/assets/css/themes/compose-ui/compose-ui-base.css b/src/assets/css/themes/compose-ui/compose-ui-base.css index dd6b513e..9c790022 100644 --- a/src/assets/css/themes/compose-ui/compose-ui-base.css +++ b/src/assets/css/themes/compose-ui/compose-ui-base.css @@ -1,8 +1,8 @@ -@import url('../../tokens/css/themes/public-theme.css') layer(theme); -@import url('../../tokens/css/themes/private-theme.css') layer(theme); -@import url('../../tokens/css/space.css') layer(theme); +/* @import url('../tokens/css/themes/public-theme.css') layer(theme); +@import url('../tokens/css/themes/private-theme.css') layer(theme); +@import url('../tokens/css/space.css') layer(theme); -@layer colors, theme-default, theme, cube; +@layer props, api, engine, colors, theme-default, theme, cube; */ @layer theme { :root { --text-xs: var(--font-scale-0); @@ -12,9 +12,7 @@ --text-xl: var(--font-scale-4); --text-xxl: var(--font-scale-5); --text-h1: var(--font-scale-6); - --_layout-depth-base: 4px; - --shadow-scale: 1.25; } } @@ -40,11 +38,45 @@ @property --unstyled { /* We define a value ("no") that doesn't exist as there's no default for "all" */ + /* https://keithclark.co.uk/articles/pseudo-boolean-css-custom-properties/ */ syntax: ''; initial-value: 0; inherits: true; } + + .border-theme-10 { + border: var(--_border-width-10) solid var(--theme-current-color); + } + + .border-theme-25 { + border: var(--_border-width-25) solid var(--theme-current-color); + } + + .border-theme-50 { + border: var(--_border-width-50) solid var(--theme-current-color); + } + + .border-theme-75 { + border: var(--_border-width-75) solid var(--theme-current-color); + } + + .border-theme-100 { + border: var(--_border-width-100) solid var(--theme-current-color); + } + + .border-theme-light { + border: var(--_border-width-small) solid var(--theme-current-color); + } + + .border-theme-medium { + border: var(--_border-width-medium) solid var(--theme-current-color); + } + + .border-theme-large { + border: var(--_border-width-large) solid var(--theme-current-color); + } + /* * Main Theme Component or element styles * A set of CSS variables are used to define the theme @@ -62,6 +94,7 @@ --TRUE: 1; --FALSE: 0; --theme: ; + /* --raw: var(--FALSE); */ --theme: ; @@ -74,29 +107,30 @@ --_component-padding-y: calc(var(--space-xs) * var(--styled)); --_component-padding-x: calc(var(--layout-space-unit) * var(--styled)); --_component-padding: var(--_component-padding-y) var(--_component-padding-x); + /* --border-width: var(--border-width-25); */ + /* --is-raw: var(--raw); */ --border-radius: 0; --base-unit: var(--_border-width-large); } + [data-compose-ui] { /* Components */ --_component-padding-x: var(--_button-padding-x); --_component-padding-y: var(--_button-padding-y); - padding: var(--_component-padding-x) var(--_component-padding-y); - --_component-border-width: calc(var(--border-width-xsmall) * var(--styled)); + padding: var(--_component-pading, var(--_component-padding-y) var(--_component-padding-x)); + --_component-border-width: calc(var(--border-width-xsmall) * var(--styled)); --theme-base-unit: var(--base-unit); --theme-base-unit-calc: calc(var(--theme-base-unit) * var(--not-raw, 1) * var(--styled, 1)); - --_component-shadow-base: var(--_shadow-xs); --_component-shadow-hover: var(--_shadow-xs); --_component-shadow-active: var(--_shadow-xs); --_component-shadow-focus: var(--_shadow-xs); --_component-shadow-disabled: 0; - --_component-transform-base: calc(-1 * var(--_shadow-xs)); --_component-transform-hover: calc(-1 * var(--_shadow-sm)); --_component-transform-active: calc(-1 * var(--_shadow-xs)); diff --git a/src/assets/css/themes/compose-ui/compose-ui.state.css b/src/assets/css/themes/compose-ui/compose-ui.state.css index cc3df2b7..3fffd1e9 100644 --- a/src/assets/css/themes/compose-ui/compose-ui.state.css +++ b/src/assets/css/themes/compose-ui/compose-ui.state.css @@ -1,5 +1,5 @@ /* state.css */ -@layer props, state, engine; +@layer props, api, engine; /* ----------------------------------------------------------------------------- * PROPS @@ -9,26 +9,36 @@ @property --state { syntax: "base | hover | active | focus | disabled"; initial-value: base; inherits: true; } /* token-or-0 */ + /* prettier-ignore */ @property --_state-base-else-0 { syntax: "base | "; initial-value: 0; inherits: true; } + /* prettier-ignore */ @property --_state-hover-else-0 { syntax: "hover | "; initial-value: 0; inherits: true; } + /* prettier-ignore */ @property --_state-active-else-0 { syntax: "active | "; initial-value: 0; inherits: true; } + /* prettier-ignore */ @property --_state-focus-else-0 { syntax: "focus | "; initial-value: 0; inherits: true; } + /* prettier-ignore */ @property --_state-disabled-else-0 { syntax: "disabled | "; initial-value: 0; inherits: true; } /* bits */ + /* prettier-ignore */ @property --is-state-base { syntax: ""; initial-value: 1; inherits: true; } + /* prettier-ignore */ @property --is-state-hover { syntax: ""; initial-value: 1; inherits: true; } + /* prettier-ignore */ @property --is-state-active { syntax: ""; initial-value: 1; inherits: true; } + /* prettier-ignore */ @property --is-state-focus { syntax: ""; initial-value: 1; inherits: true; } + /* prettier-ignore */ @property --is-state-disabled { syntax: ""; initial-value: 1; inherits: true; } } @@ -36,12 +46,40 @@ /* ----------------------------------------------------------------------------- * STATE (only sets --state) * -------------------------------------------------------------------------- */ -@layer state { - /** - * IMPORTANT: avoid unscoped :hover/:active/:focus rules. - * Only apply to the component root, otherwise everything on the page can inherit it. - */ +@layer api { + [data-compose-ui] { + /* disabled wins */ + &.disabled, + &:disabled, + &[disabled] { + --state: disabled; + } + + /* interactive states only when not disabled */ + + /* No need for `base` as it's the fallback */ + &:not([disabled], .disabled) { + &.focus, + &.focus-visible, + &:focus, + &:focus-visible { + --state: focus; + } + + &.active, + &:active { + --state: active; + } + + &.hover, + &:hover { + --state: hover; + } + } + } +} +/* [data-compose-ui]:not([disabled]):not(.disabled):not(:hover):not(:active):not(:focus):not( :focus-visible ), @@ -70,25 +108,28 @@ [data-compose-ui]:disabled, [data-compose-ui].disabled { --state: disabled; - } + } */ - /** +/** * If you REALLY need “child is hovered/focused sets parent state”, keep :has() * but scope it to the root only: */ - [data-compose-ui]:has(:hover, .hover) { - --state: hover; - } - [data-compose-ui]:has(:active, .active) { - --state: active; - } - [data-compose-ui]:has(:focus-visible, :focus, .focus-visible, .focus) { - --state: focus; - } - [data-compose-ui]:has(.disabled, :disabled, [disabled]) { - --state: disabled; - } -} + +/* [data-compose-ui]:has(:hover, .hover) { + --state: hover; + } + [data-compose-ui]:has(:active, .active) { + --state: active; + } + [data-compose-ui]:has(:focus-visible, :focus, .focus-visible, .focus) { + --state: focus; + } + [data-compose-ui]:has(.disabled, :disabled, [disabled]) { + --state: disabled; + } */ + +/* } +} */ /* ----------------------------------------------------------------------------- * ENGINE (grind -> bits, map -> s-* deltas) @@ -100,18 +141,26 @@ */ --_state-base-else-0: var(--state); --is-state-base: var(--_state-base-else-0); - --_state-hover-else-0: var(--state); --is-state-hover: var(--_state-hover-else-0); - --_state-active-else-0: var(--state); --is-state-active: var(--_state-active-else-0); - --_state-focus-else-0: var(--state); --is-state-focus: var(--_state-focus-else-0); - --_state-disabled-else-0: var(--state); --is-state-disabled: var(--_state-disabled-else-0); + --_component-transform-depth: calc( + var(--_component-transform-base) * var(--is-state-base) + var(--_component-transform-hover) * + var(--is-state-hover) + var(--_component-transform-active) * var(--is-state-active) + + var(--_component-transform-focus) * var(--is-state-focus) + + var(--_component-transform-disabled) * var(--is-state-disabled) + ); + --component-shadow-depth: calc( + var(--is-state-base) * var(--_component-shadow-base) + var(--is-state-hover) * + var(--_component-shadow-hover) + var(--is-state-active) * var(--_component-shadow-active) + + var(--is-state-focus) * var(--_component-shadow-focus) + var(--is-state-disabled) * + var(--_component-shadow-disabled) - 1 * var(--_component-transform-depth) + ); /** * 2) Map state deltas (weighted sums) @@ -141,7 +190,6 @@ var(--is-state-focus) * var(--state-focus-bg-opacity) + var(--is-state-disabled) * var(--state-disabled-bg-opacity) ); - --s-border-l: calc( var(--is-state-base) * var(--state-base-border-lightness) + var(--is-state-hover) * var(--state-hover-border-lightness) + var(--is-state-active) * @@ -169,7 +217,6 @@ var(--state-focus-border-opacity) + var(--is-state-disabled) * var(--state-disabled-border-opacity) ); - --s-text-l: calc( var(--is-state-base) * var(--state-base-text-lightness) + var(--is-state-hover) * var(--state-hover-text-lightness) + var(--is-state-active) * diff --git a/src/assets/css/themes/compose-ui/compose-ui.tone.css b/src/assets/css/themes/compose-ui/compose-ui.tone.css index 01c20e54..f894f944 100644 --- a/src/assets/css/themes/compose-ui/compose-ui.tone.css +++ b/src/assets/css/themes/compose-ui/compose-ui.tone.css @@ -9,30 +9,42 @@ @property --tone { syntax: "primary | secondary | danger | background | accent | neutral"; initial-value: primary; inherits: true; } /* token-or-0 (else-0) */ + /* prettier-ignore */ @property --_tone-primary-else-0 { syntax: "primary | "; initial-value: 0; inherits: true; } + /* prettier-ignore */ @property --_tone-secondary-else-0 { syntax: "secondary | "; initial-value: 0; inherits: true; } + /* prettier-ignore */ @property --_tone-danger-else-0 { syntax: "danger | "; initial-value: 0; inherits: true; } + /* prettier-ignore */ @property --_tone-background-else-0 { syntax: "background | "; initial-value: 0; inherits: true; } + /* prettier-ignore */ @property --_tone-accent-else-0 { syntax: "accent | "; initial-value: 0; inherits: true; } + /* prettier-ignore */ @property --_tone-neutral-else-0 { syntax: "neutral | "; initial-value: 0; inherits: true; } /* bits (invalid => initial-value 1) */ + /* prettier-ignore */ @property --is-tone-primary { syntax: ""; initial-value: 1; inherits: true; } + /* prettier-ignore */ @property --is-tone-secondary { syntax: ""; initial-value: 1; inherits: true; } + /* prettier-ignore */ @property --is-tone-danger { syntax: ""; initial-value: 1; inherits: true; } + /* prettier-ignore */ @property --is-tone-background { syntax: ""; initial-value: 1; inherits: true; } + /* prettier-ignore */ @property --is-tone-accent { syntax: ""; initial-value: 1; inherits: true; } + /* prettier-ignore */ @property --is-tone-neutral { syntax: ""; initial-value: 1; inherits: true; } } @@ -78,19 +90,14 @@ */ --_tone-primary-else-0: var(--tone); --is-tone-primary: var(--_tone-primary-else-0); - --_tone-secondary-else-0: var(--tone); --is-tone-secondary: var(--_tone-secondary-else-0); - --_tone-danger-else-0: var(--tone); --is-tone-danger: var(--_tone-danger-else-0); - --_tone-background-else-0: var(--tone); --is-tone-background: var(--_tone-background-else-0); - --_tone-accent-else-0: var(--tone); --is-tone-accent: var(--_tone-accent-else-0); - --_tone-neutral-else-0: var(--tone); --is-tone-neutral: var(--_tone-neutral-else-0); diff --git a/src/assets/css/themes/compose-ui/compose-ui.variant.css b/src/assets/css/themes/compose-ui/compose-ui.variant.css index 66492b23..5ac1f7bb 100644 --- a/src/assets/css/themes/compose-ui/compose-ui.variant.css +++ b/src/assets/css/themes/compose-ui/compose-ui.variant.css @@ -9,22 +9,29 @@ @property --variant { syntax: "contained | outlined | text"; initial-value: contained; inherits: true; } /* token-or-0 */ + /* prettier-ignore */ @property --_variant-contained-else-0 { syntax: "contained | "; initial-value: 0; inherits: true; } + /* prettier-ignore */ @property --_variant-outlined-else-0 { syntax: "outlined | "; initial-value: 0; inherits: true; } + /* prettier-ignore */ @property --_variant-text-else-0 { syntax: "text | "; initial-value: 0; inherits: true; } /* bits */ + /* prettier-ignore */ @property --is-variant-contained { syntax: ""; initial-value: 1; inherits: true; } + /* prettier-ignore */ @property --is-variant-outlined { syntax: ""; initial-value: 1; inherits: true; } + /* prettier-ignore */ @property --is-variant-text { syntax: ""; initial-value: 1; inherits: true; } /* optional numeric feature flags derived from variant */ + /* prettier-ignore */ @property --has-border { syntax: ""; initial-value: 0; inherits: true; } } @@ -56,10 +63,8 @@ */ --_variant-contained-else-0: var(--variant); --is-variant-contained: var(--_variant-contained-else-0); - --_variant-outlined-else-0: var(--variant); --is-variant-outlined: var(--_variant-outlined-else-0); - --_variant-text-else-0: var(--variant); --is-variant-text: var(--_variant-text-else-0); @@ -192,8 +197,10 @@ --component-border-width-effective: calc( var(--has-border) * var(--component-border-width, 0px) ); + border-width: var(--component-border-width-effective); border-style: var(--component-border-style, solid); + /* border-color can stay computed later (you already do border-color: oklch(...)) */ } } diff --git a/src/assets/css/themes/core.css b/src/assets/css/themes/core.css new file mode 100644 index 00000000..d71ca1a7 --- /dev/null +++ b/src/assets/css/themes/core.css @@ -0,0 +1,11 @@ +@import './tokens/css/colors.css' layer(colors); +@import './tokens/css/themes/public-theme.css' layer(theme); +@import './tokens/css/themes/private-theme.css' layer(theme); + +/* TODO: fix */ +@import './tokens/css/border/border.css' layer(theme); +@import './tokens/css/space.css' layer(theme); + +/* CUBE Utilities */ +@import './tokens/css/cube/cube.utility.css' layer(cube); +@layer props, api, engine, colors, theme-default, theme, cube; diff --git a/src/assets/css/themes/private-theme.css b/src/assets/css/themes/private-theme.css index 8e5c54d5..946431f7 100644 --- a/src/assets/css/themes/private-theme.css +++ b/src/assets/css/themes/private-theme.css @@ -5,20 +5,26 @@ */ :root { /* -------------------------------------------------- */ + /* Border */ + /* -------------------------------------------------- */ --_border-width-default: var(--border-width-default, 2px); --_border-style-default: var(--border-style-default, solid); --_border-radius-default: var(--border-radius-default, 0); /* -------------------------------------------------- */ + /* Color */ + /* -------------------------------------------------- */ --_color-shadow-dark: var(--color-shadow-dark, #616970); - --_color-shadow-light: var(--color-shadow-light, rgba(255, 255, 255, 0.25)); + --_color-shadow-light: var(--color-shadow-light, rgb(255 255 255 / 25%)); /* -------------------------------------------------- */ + /* Breakpoints */ + /* -------------------------------------------------- */ --_breakpoints-mobile: var(--breakpoints-mobile, 640px); --_breakpoints-tablet: var(--breakpoints-tablet, 768px); @@ -27,13 +33,17 @@ --_breakpoints-desktop-xxl: var(--breakpoints-desktop-xxl, 1820px); /* -------------------------------------------------- */ + /* Layout */ + /* -------------------------------------------------- */ --_layout-zIndex: var(--layout-zIndex, 1000); --_layout-depth-base: var(--layout-depth-base, 6px); /* -------------------------------------------------- */ + /* Component */ + /* -------------------------------------------------- */ --_component-shadow-base: var(--component-shadow-base, 0.25); --_component-shadow-hover: var(--component-shadow-hover, 0.25); @@ -47,7 +57,9 @@ --_component-transform-disabled: var(--component-transform-disabled, 0); /* -------------------------------------------------- */ + /* Space */ + /* -------------------------------------------------- */ --_space-unit: var(--space-unit, 1rem); --_space-xxs: var(--space-xxs, calc(0.25 * var(--space-unit))); @@ -59,7 +71,9 @@ --_space-xxl: var(--space-xxl, calc(4 * var(--space-unit))); /* -------------------------------------------------- */ + /* Font */ + /* -------------------------------------------------- */ --_font-regular: var(--font-regular, url('/fonts/GOTHAM-BOOK.OTF')); --_font-bold: var(--font-bold, url('/fonts/GOTHAM-BOLD.OTF')); @@ -67,7 +81,9 @@ --_font-bolder-italic: var(--font-bolder-italic, url('/fonts/GOTHAM-BLACKITALIC.OTF')); /* -------------------------------------------------- */ + /* Text */ + /* -------------------------------------------------- */ --_text-xs: var(--text-xs, clamp(0.4444rem, 0.6881rem - 0.2407vw, 0.64rem)); --_text-sm: var(--text-sm, clamp(0.6667rem, 0.8328rem - 0.1641vw, 0.8rem)); @@ -78,7 +94,9 @@ --_text-h1: var(--text-h1, clamp(2.4414rem, 1.7962rem + 3.226vi, 5.0625rem)); /* -------------------------------------------------- */ + /* Heading */ + /* -------------------------------------------------- */ --_heading-height: var(--heading-height, calc(1rem * 2.5)); } diff --git a/src/assets/css/themes/public-theme.css b/src/assets/css/themes/public-theme.css index 7338c24e..6318ff1c 100644 --- a/src/assets/css/themes/public-theme.css +++ b/src/assets/css/themes/public-theme.css @@ -5,20 +5,26 @@ */ :root { /* -------------------------------------------------- */ + /* Border */ + /* -------------------------------------------------- */ --border-width-default: 2px; --border-style-default: solid; --border-radius-default: 0; /* -------------------------------------------------- */ + /* Color */ + /* -------------------------------------------------- */ --color-shadow-dark: #616970; - --color-shadow-light: rgba(255, 255, 255, 0.25); + --color-shadow-light: rgb(255 255 255 / 25%); /* -------------------------------------------------- */ + /* Breakpoints */ + /* -------------------------------------------------- */ --breakpoints-mobile: 640px; --breakpoints-tablet: 768px; @@ -27,13 +33,17 @@ --breakpoints-desktop-xxl: 1820px; /* -------------------------------------------------- */ + /* Layout */ + /* -------------------------------------------------- */ --layout-zIndex: 1000; --layout-depth-base: 6px; /* -------------------------------------------------- */ + /* Component */ + /* -------------------------------------------------- */ --component-shadow-base: 0.25; --component-shadow-hover: 0.25; @@ -47,7 +57,9 @@ --component-transform-disabled: 0; /* -------------------------------------------------- */ + /* Space */ + /* -------------------------------------------------- */ --space-unit: 1rem; --space-xxs: calc(0.25 * var(--space-unit)); @@ -59,7 +71,9 @@ --space-xxl: calc(4 * var(--space-unit)); /* -------------------------------------------------- */ + /* Font */ + /* -------------------------------------------------- */ --font-regular: url('/fonts/GOTHAM-BOOK.OTF'); --font-bold: url('/fonts/GOTHAM-BOLD.OTF'); @@ -67,7 +81,9 @@ --font-bolder-italic: url('/fonts/GOTHAM-BLACKITALIC.OTF'); /* -------------------------------------------------- */ + /* Text */ + /* -------------------------------------------------- */ --text-xs: clamp(0.4444rem, 0.6881rem - 0.2407vw, 0.64rem); --text-sm: clamp(0.6667rem, 0.8328rem - 0.1641vw, 0.8rem); @@ -78,7 +94,9 @@ --text-h1: clamp(2.4414rem, 1.7962rem + 3.226vi, 5.0625rem); /* -------------------------------------------------- */ + /* Heading */ + /* -------------------------------------------------- */ --heading-height: calc(1rem * 2.5); } diff --git a/src/assets/css/tokens/css/bg/bg.css b/src/assets/css/themes/tokens/css/bg/bg.css similarity index 85% rename from src/assets/css/tokens/css/bg/bg.css rename to src/assets/css/themes/tokens/css/bg/bg.css index 518afbc1..e357e540 100644 --- a/src/assets/css/tokens/css/bg/bg.css +++ b/src/assets/css/themes/tokens/css/bg/bg.css @@ -3,22 +3,22 @@ */ :root { - --color-bg-page: #2a2b2a; - --color-bg-subtle: #dce0dc; + --color-bg-page: #edda9f; + --color-bg-subtle: #edda9f; --color-bg-elevated: #ffffff; - --color-bg-inset: #b5b8b5; + --color-bg-inset: #c2b382; --color-bg-primary: #65572a; - --color-bg-primary-hover: #403718; + --color-bg-primary-hover: oklch(from #65572a lightness(+7%)); --color-bg-primary-active: #1e1908; --color-bg-primary-subtle: #fbefd2; --color-bg-accent: #b4363b; --color-bg-accent-hover: #7a2225; --color-bg-accent-subtle: #fbeeee; - --color-bg-neutral: #4e4731; + --color-bg-neutral: #494b49; --color-bg-neutral-strong: #010101; - --color-bg-info: #fbeeee; + --color-bg-info: #ac9f70; --color-bg-warning: #fbefd2; - --color-bg-success: #edda9f; + --color-bg-success: #dce0dc; --color-bg-secondary-lightness: var(--color-secondary-lightness, 0); --color-bg-secondary-chroma: var(--color-secondary-chroma, 0); --color-bg-secondary-hue: var(--color-secondary-hue, 0); @@ -45,14 +45,14 @@ --bg-accent-active: #450f11; --bg-accent-focus: #fbeeee; --bg-accent-disable: #fbeeee; - --bg-neutral: #4e4731; - --bg-neutral-hover: #2c271a; - --bg-neutral-active: #131109; - --bg-neutral-focus: #edda9f; - --bg-neutral-disable: #edda9f; + --bg-neutral: #494b49; + --bg-neutral-hover: #2a2b2a; + --bg-neutral-active: #101110; + --bg-neutral-focus: #dce0dc; + --bg-neutral-disable: #dce0dc; --bg-info: #fbeeee; --bg-warning: #fbefd2; - --bg-success: #edda9f; + --bg-success: #dce0dc; --component-bg-lightness: calc(var(--color-bg-lightness) + var(--variant-bg-lightness) + var(--state-bg-lightness)); --component-bg-chroma: calc(var(--color-bg-chroma) + var(--variant-bg-chroma) + var(--state-bg-chroma)); --component-bg-hue: calc(var(--color-bg-hue)); diff --git a/src/assets/css/tokens/css/border/border.css b/src/assets/css/themes/tokens/css/border/border.css similarity index 92% rename from src/assets/css/tokens/css/border/border.css rename to src/assets/css/themes/tokens/css/border/border.css index 2150e2ad..249d1e00 100644 --- a/src/assets/css/tokens/css/border/border.css +++ b/src/assets/css/themes/tokens/css/border/border.css @@ -5,6 +5,7 @@ :root { --border-width-base: 2px; --border-width-scale: 1.25; + --border-width-default: var(--border-width-base); --border-width-xsmall: calc(var(--border-width-base) / 2 * var(--border-width-scale)); --border-width-small: calc(var(--border-width-base) * var(--border-width-scale)); --border-width-medium: var(--border-width-base); @@ -21,14 +22,15 @@ --border-radius-base: 0; --border-radius-0-5: 0.5px; --border-radius-scale: 1.5; - --color-border-subtle: #b5b8b5; - --color-border-default: #8f928f; - --color-border-strong: #6b6d6b; + --color-border-subtle: #c2b382; + --color-border-default: #998d65; + --color-border-strong: #72694b; --color-border-primary: #65572a; --color-border-focus: #b4363b; --color-border-info: #f3cbcc; --color-border-warning: #e3c567; - --color-border-success: #c2b382; + --color-border-success: #b5b8b5; + --color-border-neutral: #8f928f; --color-border-secondary-lightness: var(--color-secondary-lightness, 0); --color-border-secondary-chroma: var(--color-secondary-chroma, 0); --color-border-secondary-hue: var(--color-secondary-hue, 0); diff --git a/src/assets/css/tokens/css/colors.css b/src/assets/css/themes/tokens/css/colors.css similarity index 83% rename from src/assets/css/tokens/css/colors.css rename to src/assets/css/themes/tokens/css/colors.css index 023078aa..f9655d92 100644 --- a/src/assets/css/tokens/css/colors.css +++ b/src/assets/css/themes/tokens/css/colors.css @@ -123,16 +123,16 @@ --color-primary-800: var(--color-yellow-800); --color-primary-900: var(--color-yellow-900); --color-primary-base: var(--color-yellow-base); ---color-secondary-100: var(--color-graphite-100); ---color-secondary-200: var(--color-graphite-200); ---color-secondary-300: var(--color-graphite-300); ---color-secondary-400: var(--color-graphite-400); ---color-secondary-500: var(--color-graphite-500); ---color-secondary-600: var(--color-graphite-600); ---color-secondary-700: var(--color-graphite-700); ---color-secondary-800: var(--color-graphite-800); ---color-secondary-900: var(--color-graphite-900); ---color-secondary-base: var(--color-graphite-base); +--color-secondary-100: var(--color-vanilla-custard-100); +--color-secondary-200: var(--color-vanilla-custard-200); +--color-secondary-300: var(--color-vanilla-custard-300); +--color-secondary-400: var(--color-vanilla-custard-400); +--color-secondary-500: var(--color-vanilla-custard-500); +--color-secondary-600: var(--color-vanilla-custard-600); +--color-secondary-700: var(--color-vanilla-custard-700); +--color-secondary-800: var(--color-vanilla-custard-800); +--color-secondary-900: var(--color-vanilla-custard-900); +--color-secondary-base: var(--color-vanilla-custard-base); --color-accent-100: var(--color-intense-cherry-100); --color-accent-200: var(--color-intense-cherry-200); --color-accent-300: var(--color-intense-cherry-300); @@ -143,16 +143,25 @@ --color-accent-800: var(--color-intense-cherry-800); --color-accent-900: var(--color-intense-cherry-900); --color-accent-base: var(--color-intense-cherry-base); ---color-neutral-100: var(--color-vanilla-custard-100); ---color-neutral-200: var(--color-vanilla-custard-200); ---color-neutral-300: var(--color-vanilla-custard-300); ---color-neutral-400: var(--color-vanilla-custard-400); ---color-neutral-500: var(--color-vanilla-custard-500); ---color-neutral-600: var(--color-vanilla-custard-600); ---color-neutral-700: var(--color-vanilla-custard-700); ---color-neutral-800: var(--color-vanilla-custard-800); ---color-neutral-900: var(--color-vanilla-custard-900); ---color-neutral-base: var(--color-vanilla-custard-base); +--color-neutral-100: var(--color-graphite-100); +--color-neutral-200: var(--color-graphite-200); +--color-neutral-300: var(--color-graphite-300); +--color-neutral-400: var(--color-graphite-400); +--color-neutral-500: var(--color-graphite-500); +--color-neutral-600: var(--color-graphite-600); +--color-neutral-700: var(--color-graphite-700); +--color-neutral-800: var(--color-graphite-800); +--color-neutral-900: var(--color-graphite-900); +--color-neutral-base: var(--color-graphite-base); +--color-info-100: var(--color-vanilla-cream-300); +--color-info-200: var(--color-vanilla-cream-500); +--color-info-300: var(--color-vanilla-cream-700); +--color-info-400: var(--color-vanilla-cream-900); +--color-info-500: var(--color-vanilla-cream-base); +--color-info-600: var(--color-vanilla-cream-100); +--color-info-700: var(--color-vanilla-cream-200); +--color-info-800: var(--color-vanilla-cream-400); +--color-info-900: var(--color-vanilla-cream-600); /* ------------------------------------------------------------ */ /* Intent */ @@ -162,7 +171,7 @@ --color-bg-elevated: #ffffff; --color-bg-inset: var(--color-secondary-200); --color-bg-primary: var(--color-primary-500); ---color-bg-primary-hover: var(--color-primary-600); +--color-bg-primary-hover: oklch(from var(--color-primary-500) lightness(+7%)); --color-bg-primary-active: var(--color-primary-700); --color-bg-primary-subtle: var(--color-primary-100); --color-bg-accent: var(--color-accent-500); @@ -170,7 +179,7 @@ --color-bg-accent-subtle: var(--color-accent-100); --color-bg-neutral: var(--color-neutral-500); --color-bg-neutral-strong: var(--color-neutral-900); ---color-bg-info: var(--color-accent-100); +--color-bg-info: var(--color-info-100); --color-bg-warning: var(--color-primary-100); --color-bg-success: var(--color-neutral-100); --color-text-primary: var(--color-secondary-900); @@ -190,5 +199,6 @@ --color-border-info: var(--color-accent-200); --color-border-warning: var(--color-primary-200); --color-border-success: var(--color-neutral-200); +--color-border-neutral: var(--color-neutral-300); --color-feedback-error: var(--color-accent-base); } \ No newline at end of file diff --git a/src/assets/css/tokens/css/conditional.css b/src/assets/css/themes/tokens/css/conditional.css similarity index 100% rename from src/assets/css/tokens/css/conditional.css rename to src/assets/css/themes/tokens/css/conditional.css diff --git a/src/assets/css/tokens/css/cube/cube.block.css b/src/assets/css/themes/tokens/css/cube/cube.block.css similarity index 83% rename from src/assets/css/tokens/css/cube/cube.block.css rename to src/assets/css/themes/tokens/css/cube/cube.block.css index 91c64024..e8cf2574 100644 --- a/src/assets/css/tokens/css/cube/cube.block.css +++ b/src/assets/css/themes/tokens/css/cube/cube.block.css @@ -10,10 +10,9 @@ --cube-block-button-padding-x: var(--_spacing-sm); --cube-block-button-padding-y: var(--_spacing-xs); --cube-block-button-radius: var(--_border-radius-medium); - --cube-block-button-color: var(--_color-text-primary); --cube-block-button-text: var(--_color-text-primary); --cube-block-button-bg: var(--_color-bg-primary); - --cube-block-button-hover-background: var(--_color-bg-primary-hover); + --cube-block-button-bg-hover: var(--_color-bg-primary-hover); --cube-block-checkbox-bg: var(--_color-bg-primary); --cube-block-checkbox-padding: var(--_spacing-xs); } diff --git a/src/assets/css/themes/tokens/css/cube/cube.composition.css b/src/assets/css/themes/tokens/css/cube/cube.composition.css new file mode 100644 index 00000000..589afaef --- /dev/null +++ b/src/assets/css/themes/tokens/css/cube/cube.composition.css @@ -0,0 +1,16 @@ +/** + * Do not edit directly, this file was auto-generated. + */ + +:root { + --cube-composition-flow-space: var(--gutter); + --cube-composition-stack-gap: var(--gutter); + --cube-composition-stack-align: start; + --cube-composition-stack-direction: var(--layout-direction); + --cube-composition-cluster-gap: var(--gutter); + --cube-composition-cluster-align: center; + --cube-composition-center-max-width: 72ch; + --cube-composition-center-padding-inline: var(--gutter); + --cube-composition-switcher-modifier: var(--layout-break-at); + --cube-composition-switcher-gap: var(--gutter); +} diff --git a/src/assets/css/themes/tokens/css/cube/cube.utility.css b/src/assets/css/themes/tokens/css/cube/cube.utility.css new file mode 100644 index 00000000..77ee6468 --- /dev/null +++ b/src/assets/css/themes/tokens/css/cube/cube.utility.css @@ -0,0 +1,185 @@ + +/* ------------------------------------------------------------ */ +/* Margin */ +/* ------------------------------------------------------------ */ +.margin-t-0 { margin-block-start: 0 } +.margin-t-xs { margin-block-start: var(--spacing-xs) } +.margin-t-sm { margin-block-start: var(--spacing-sm) } +.margin-t-md { margin-block-end: var(--spacing-md) } +.margin-t-lg { margin-block-end: var(--spacing-lg) } +.margin-t-xl { margin-block-start: var(--spacing-xl) } +.margin-b-0 { margin-block-end: 0 } +.margin-b-xs { margin-block-end: var(--spacing-xs) } +.margin-b-sm { margin-block-end: var(--spacing-sm) } +.margin-b-md { margin-block-end: var(--spacing-md) } +.margin-b-lg { margin-block-end: var(--spacing-lg) } +.margin-b-xl { margin-block-end: var(--spacing-xl) } +.margin-auto { margin: auto } + +/* ------------------------------------------------------------ */ +/* Position */ +/* ------------------------------------------------------------ */ +.position-relative { position: relative } +.position-absolute { position: absolute } +.position-fixed { position: fixed } +.position-top-0 { top: 0 } +.position-right-0 { right: 0 } +.position-bottom-0 { bottom: 0 } +.position-left-0 { left: 0 } + +/* ------------------------------------------------------------ */ +/* Display */ +/* ------------------------------------------------------------ */ +.none { display: none } +.block { display: block } +.inline-block { display: inline-block } +.grid { display: grid } +.flex { display: flex } +.sticky { position: sticky } + +/* ------------------------------------------------------------ */ +/* Align */ +/* ------------------------------------------------------------ */ +.align-start { --layout-align: flex-start } +.align-end { --layout-align: flex-end } +.align-center { --layout-align: center } + +/* ------------------------------------------------------------ */ +/* Justify */ +/* ------------------------------------------------------------ */ +.justify-start { --layout-justify: flex-start } +.justify-end { --layout-justify: flex-end } +.justify-center { --layout-justify: center } +.justify-between { --layout-justify: space-between } + +/* ------------------------------------------------------------ */ +/* Flex */ +/* ------------------------------------------------------------ */ +.flex-column { --layout-direction: column } +.flex-row { --layout-direction: row } +.flex-wrap { flex-wrap: wrap } + +/* ------------------------------------------------------------ */ +/* Gap */ +/* ------------------------------------------------------------ */ +.gap-xs { gap: var(--spacing-xs) } +.gap-sm { gap: var(--spacing-sm) } +.gap-md { gap: var(--spacing-md) } +.gap-lg { gap: var(--spacing-lg) } +.gap-xl { gap: var(--spacing-xl) } + +/* ------------------------------------------------------------ */ +/* Padding */ +/* ------------------------------------------------------------ */ +.padding-xs { padding: var(--spacing-xs) } +.padding-sm { padding: var(--spacing-sm) } +.padding-md { padding: var(--spacing-md) } +.padding-lg { padding: var(--spacing-lg) } +.padding-xl { padding: var(--spacing-xl) } +.padding-x-0 { padding-inline: 0 } +.padding-x-xs { padding-inline: var(--spacing-xs) } +.padding-x-sm { padding-inline: var(--spacing-sm) } +.padding-x-md { padding-inline: var(--spacing-md) } +.padding-x-lg { padding-inline: var(--spacing-lg) } +.padding-x-xl { padding-inline: var(--spacing-xl) } +.padding-y-0 { padding-block: 0 } +.padding-y-xs { padding-block: var(--spacing-xs) } +.padding-y-sm { padding-block: var(--spacing-sm) } +.padding-y-md { padding-block: var(--spacing-md) } +.padding-y-lg { padding-block: var(--spacing-lg) } +.padding-y-xl { padding-block: var(--spacing-xl) } +.padding-auto { padding: 0 } +.padding-top-0 { padding-top: 0 } +.padding-top-xs { padding-top: var(--spacing-xs) } +.padding-top-sm { padding-top: var(--spacing-sm) } +.padding-top-md { padding-top: var(--spacing-md) } +.padding-top-lg { padding-top: var(--spacing-lg) } +.padding-top-xl { padding-top: var(--spacing-xl) } +.padding-bottom-0 { padding-bottom: 0 } + +/* ------------------------------------------------------------ */ +/* Text */ +/* ------------------------------------------------------------ */ +.text-center { text-align: center } +.text-dim { opacity: 0.7 } + +/* ------------------------------------------------------------ */ +/* Border */ +/* ------------------------------------------------------------ */ +.border-solid { border-style: solid } +.border-dashed { border-style: dashed } +.border-dotted { border-style: dotted } +.border-none { border-style: none } +.border-primary { border-color: var(--color-border-primary) } +.border-secondary { border-color: var(--color-border-secondary) } +.border-accent { border-color: var(--color-border-accent) } +.border-neutral { border-color: var(--color-border-neutral) } +.border-info { border-color: var(--color-border-info) } +.border-success { border-color: var(--color-border-success) } +.border-top { border-top-width: var(--border-width-default) } +.border-bottom { border-bottom-width: var(--border-width-default) } +.border-left { border-left-width: var(--border-width-default) } +.border-right { border-right-width: var(--border-width-default) } +.border-all { border-width: var(--border-width-default) } +.border-theme-10 { border: var(--border-width-10) solid var(--theme-color) } +.border-theme-25 { border: var(--border-width-25) solid var(--theme-color) } +.border-theme-50 { border: var(--border-width-50) solid var(--theme-color) } +.border-theme-75 { border: var(--border-width-75) solid var(--theme-color) } +.border-theme-100 { border: var(--border-width-100) solid var(--theme-color) } +.border-theme-light { border: var(--border-width-small) solid var(--theme-color) } +.border-theme-medium { border: var(--border-width-medium) solid var(--theme-color) } +.border-theme-large { border: var(--border-width-large) solid var(--theme-color) } +.border-width-xsmall { border-width: var(--border-width-xsmall) } +.border-width-small { border-width: var(--border-width-small) } +.border-width-medium { border-width: var(--border-width-medium) } +.border-width-large { border-width: var(--border-width-large) } + +/* ------------------------------------------------------------ */ +/* Radius */ +/* ------------------------------------------------------------ */ +.radius-light { border-radius: var(--radius-light) } +.radius-medium { border-radius: var(--radius-medium) } +.radius-heavy { border-radius: var(--radius-heavy) } + +/* ------------------------------------------------------------ */ +/* Height */ +/* ------------------------------------------------------------ */ +.height-auto { height: auto } +.height-full { height: 100% } +.height-half { height: 50% } +.height-quarter { height: 25% } +.height-screen { height: 100svh } + +/* ------------------------------------------------------------ */ +/* Width */ +/* ------------------------------------------------------------ */ +.width-auto { width: auto } +.width-full { width: 100% } +.width-half { width: 50% } +.width-quarter { width: 25% } +.width-screen { width: 100svw } + +/* ------------------------------------------------------------ */ +/* Overflow */ +/* ------------------------------------------------------------ */ +.overflow-auto { overflow: auto } +.overflow-hidden { overflow: hidden } +.overflow-scroll { overflow: scroll } +.overflow-visible { overflow: visible } +.overflow-x-hidden { overflow-x: hidden } +.overflow-y-hidden { overflow-y: hidden } + +/* ------------------------------------------------------------ */ +/* Bg */ +/* ------------------------------------------------------------ */ +.bg-primary { background-color: var(--color-bg-primary) } +.bg-secondary { background-color: var(--color-bg-secondary) } +.bg-accent { background-color: var(--color-bg-accent) } +.bg-accent-subtle { background-color: var(--color-bg-accent-subtle) } +.bg-neutral { background-color: var(--color-bg-neutral) } +.bg-page { background-color: var(--color-bg-page) } +.bg-subtle { background-color: var(--color-bg-subtle) } +.bg-elevated { background-color: var(--color-bg-elevated) } +.bg-inset { background-color: var(--color-bg-inset) } +.bg-info { background-color: var(--color-bg-info) } +.bg-success { background-color: var(--color-bg-success) } diff --git a/src/assets/css/tokens/css/font/font.css b/src/assets/css/themes/tokens/css/font/font.css similarity index 97% rename from src/assets/css/tokens/css/font/font.css rename to src/assets/css/themes/tokens/css/font/font.css index 9dfcf0cb..ee2c8e9f 100644 --- a/src/assets/css/tokens/css/font/font.css +++ b/src/assets/css/themes/tokens/css/font/font.css @@ -18,7 +18,7 @@ --font-scale-max: 1.2; --font-steps: 0,1,2,3,4,5,6; --font-weight-light: 300; - --font-weight-regular: 400; + --font-weight-normal: 400; --font-weight-medium: 500; --font-weight-bold: 700; } diff --git a/src/assets/css/tokens/css/space.css b/src/assets/css/themes/tokens/css/space.css similarity index 100% rename from src/assets/css/tokens/css/space.css rename to src/assets/css/themes/tokens/css/space.css diff --git a/src/assets/css/tokens/css/text/text.css b/src/assets/css/themes/tokens/css/text/text.css similarity index 94% rename from src/assets/css/tokens/css/text/text.css rename to src/assets/css/themes/tokens/css/text/text.css index 96d188fa..09edae99 100644 --- a/src/assets/css/tokens/css/text/text.css +++ b/src/assets/css/themes/tokens/css/text/text.css @@ -4,14 +4,14 @@ :root { --color-text-primary: #010101; - --color-text-secondary: #101110; - --color-text-muted: #494b49; - --color-text-subtle: #6b6d6b; + --color-text-secondary: #131109; + --color-text-muted: #4e4731; + --color-text-subtle: #72694b; --color-text-link: #450f11; --color-text-link-hover: #1c0304; --color-text-info: #450f11; --color-text-warning: #1e1908; - --color-text-success: #131109; + --color-text-success: #101110; --color-text-danger-lightness: var(--color-danger-lightness, 0); --color-text-danger-chroma: var(--color-danger-chroma, 0); --color-text-danger-hue: var(--color-danger-hue, 0); diff --git a/src/assets/css/tokens/css/themes/private-theme.css b/src/assets/css/themes/tokens/css/themes/private-theme.css similarity index 93% rename from src/assets/css/tokens/css/themes/private-theme.css rename to src/assets/css/themes/tokens/css/themes/private-theme.css index d1def689..8eceb80a 100644 --- a/src/assets/css/tokens/css/themes/private-theme.css +++ b/src/assets/css/themes/tokens/css/themes/private-theme.css @@ -9,6 +9,7 @@ /* ------------------------------------------------------------ */ --_border-width-base: var(--border-width-base, 2px); --_border-width-scale: var(--border-width-scale, 1.25); + --_border-width-default: var(--border-width-default, var(--border-width-base)); --_border-width-xsmall: var(--border-width-xsmall, calc(var(--border-width-base) / 2 * var(--border-width-scale))); --_border-width-small: var(--border-width-small, calc(var(--border-width-base) * var(--border-width-scale))); --_border-width-medium: var(--border-width-medium, var(--border-width-base)); @@ -54,7 +55,7 @@ --_font-scale-max: var(--font-scale-max, 1.2); --_font-steps: var(--font-steps, 0,1,2,3,4,5,6); --_font-weight-light: var(--font-weight-light, 300); - --_font-weight-regular: var(--font-weight-regular, 400); + --_font-weight-normal: var(--font-weight-normal, 400); --_font-weight-medium: var(--font-weight-medium, 500); --_font-weight-bold: var(--font-weight-bold, 700); @@ -113,6 +114,7 @@ --_layout-overlay-blur: var(--layout-overlay-blur, 8px); --_layout-space-unit: var(--layout-space-unit, var(--_space-unit-fluid)); --_layout-depth-base: var(--layout-depth-base, 6px); + --_layout-mobile-padding: var(--layout-mobile-padding, var(--_spacing-md)); /* ------------------------------------------------------------ */ /* Radius */ @@ -186,6 +188,27 @@ /* Cube */ /* ------------------------------------------------------------ */ + /* -------------------- */ + /* Global */ + /* -------------------- */ + --_gutter: var(--gutter, var(--layout-gutter-sm)); + --_on: var(--on, initial); + --_off: var(--off, ); + + /* -------------------- */ + /* Composition */ + /* -------------------- */ + --_flow-space: var(--flow-space, var(--gutter)); + --_stack-gap: var(--stack-gap, var(--gutter)); + --_stack-align: var(--stack-align, start); + --_stack-direction: var(--stack-direction, var(--layout-direction)); + --_cluster-gap: var(--cluster-gap, var(--gutter)); + --_cluster-align: var(--cluster-align, center); + --_center-max-width: var(--center-max-width, 72ch); + --_center-padding-inline: var(--center-padding-inline, var(--gutter)); + --_switcher-modifier: var(--switcher-modifier, var(--layout-break-at)); + --_switcher-gap: var(--switcher-gap, var(--gutter)); + /* -------------------- */ /* Block */ /* -------------------- */ @@ -196,25 +219,10 @@ --_button-padding-x: var(--button-padding-x, var(--_spacing-sm)); --_button-padding-y: var(--button-padding-y, var(--_spacing-xs)); --_button-radius: var(--button-radius, var(--_border-radius-medium)); - --_button-color: var(--button-color, var(--_color-text-primary)); --_button-text: var(--button-text, var(--_color-text-primary)); --_button-bg: var(--button-bg, var(--_color-bg-primary)); - --_button-hover-background: var(--button-hover-background, var(--_color-bg-primary-hover)); + --_button-bg-hover: var(--button-bg-hover, var(--_color-bg-primary-hover)); --_checkbox-bg: var(--checkbox-bg, var(--_color-bg-primary)); --_checkbox-padding: var(--checkbox-padding, var(--_spacing-xs)); - /* -------------------- */ - /* Composition */ - /* -------------------- */ - --_flow-space: var(--flow-space, var(--_layout-gutter-md)); - --_stack-gap: var(--stack-gap, var(--_layout-gutter-md)); - --_stack-align: var(--stack-align, start); - --_stack-direction: var(--stack-direction, var(--__layout-direction, column)); - --_cluster-gap: var(--cluster-gap, var(--_layout-gutter-sm)); - --_cluster-align: var(--cluster-align, center); - --_center-max-width: var(--center-max-width, 72ch); - --_center-padding-inline: var(--center-padding-inline, var(--_layout-gutter-md)); - --_switcher-modifier: var(--switcher-modifier, var(--__layout-break-at)); - --_switcher-gap: var(--switcher-gap, var(--_layout-gutter-sm)); - } diff --git a/src/assets/css/tokens/css/themes/public-theme.css b/src/assets/css/themes/tokens/css/themes/public-theme.css similarity index 94% rename from src/assets/css/tokens/css/themes/public-theme.css rename to src/assets/css/themes/tokens/css/themes/public-theme.css index ec612653..dffd7a5e 100644 --- a/src/assets/css/tokens/css/themes/public-theme.css +++ b/src/assets/css/themes/tokens/css/themes/public-theme.css @@ -9,6 +9,7 @@ /* ------------------------------------------------------------ */ --border-width-base: 2px; --border-width-scale: 1.25; + --border-width-default: var(--border-width-base); --border-width-xsmall: calc(var(--border-width-base) / 2 * var(--border-width-scale)); --border-width-small: calc(var(--border-width-base) * var(--border-width-scale)); --border-width-medium: var(--border-width-base); @@ -54,7 +55,7 @@ --font-scale-max: 1.2; --font-steps: 0,1,2,3,4,5,6; --font-weight-light: 300; - --font-weight-regular: 400; + --font-weight-normal: 400; --font-weight-medium: 500; --font-weight-bold: 700; @@ -113,6 +114,7 @@ --layout-overlay-blur: 8px; --layout-space-unit: var(--space-unit-fluid); --layout-depth-base: 6px; + --layout-mobile-padding: var(--spacing-md); /* ------------------------------------------------------------ */ /* Radius */ @@ -186,6 +188,27 @@ /* Cube */ /* ------------------------------------------------------------ */ + /* -------------------- */ + /* Global */ + /* -------------------- */ + --gutter: var(--layout-gutter-sm); + --on: initial; + --off: ; + + /* -------------------- */ + /* Composition */ + /* -------------------- */ + --flow-space: var(--gutter); + --stack-gap: var(--gutter); + --stack-align: start; + --stack-direction: var(--layout-direction); + --cluster-gap: var(--gutter); + --cluster-align: center; + --center-max-width: 72ch; + --center-padding-inline: var(--gutter); + --switcher-modifier: var(--layout-break-at); + --switcher-gap: var(--gutter); + /* -------------------- */ /* Block */ /* -------------------- */ @@ -196,25 +219,10 @@ --button-padding-x: var(--_spacing-sm); --button-padding-y: var(--_spacing-xs); --button-radius: var(--_border-radius-medium); - --button-color: var(--_color-text-primary); --button-text: var(--_color-text-primary); --button-bg: var(--_color-bg-primary); - --button-hover-background: var(--_color-bg-primary-hover); + --button-bg-hover: var(--_color-bg-primary-hover); --checkbox-bg: var(--_color-bg-primary); --checkbox-padding: var(--_spacing-xs); - /* -------------------- */ - /* Composition */ - /* -------------------- */ - --flow-space: var(--_layout-gutter-md); - --stack-gap: var(--_layout-gutter-md); - --stack-align: start; - --stack-direction: var(--__layout-direction, column); - --cluster-gap: var(--_layout-gutter-sm); - --cluster-align: center; - --center-max-width: 72ch; - --center-padding-inline: var(--_layout-gutter-md); - --switcher-modifier: var(--__layout-break-at); - --switcher-gap: var(--_layout-gutter-sm); - } diff --git a/src/assets/css/tokens/css/variant/variant.css b/src/assets/css/themes/tokens/css/variant/variant.css similarity index 100% rename from src/assets/css/tokens/css/variant/variant.css rename to src/assets/css/themes/tokens/css/variant/variant.css diff --git a/src/assets/css/tokens/css/variants.css b/src/assets/css/themes/tokens/css/variants.css similarity index 100% rename from src/assets/css/tokens/css/variants.css rename to src/assets/css/themes/tokens/css/variants.css diff --git a/src/assets/css/themes/tokens/types/theme.d.ts b/src/assets/css/themes/tokens/types/theme.d.ts new file mode 100644 index 00000000..3cabc74b --- /dev/null +++ b/src/assets/css/themes/tokens/types/theme.d.ts @@ -0,0 +1,932 @@ +/** + * Do not edit directly, this file was auto-generated. + */ + +export interface DesignTokens { + border: { + width: { + base: string; + scale: string; + default: string; + xsmall: string; + small: string; + medium: string; + large: string; + }; + style: { + solid: string; + dashed: string; + dotted: string; + double: string; + none: string; + default: string; + }; + radius: { + '1': string; + '2': string; + '4': string; + base: string; + '0.5': string; + scale: string; + }; + }; + breakpoint: { + xs: string; + sm: string; + md: string; + lg: string; + xl: string; + xxl: string; + }; + 'color-pool': { + 'straw-gold': { + '100': string; + '200': string; + '300': string; + '400': string; + '500': string; + '600': string; + '700': string; + '800': string; + '900': string; + base: string; + }; + graphite: { + '100': string; + '200': string; + '300': string; + '400': string; + '500': string; + '600': string; + '700': string; + '800': string; + '900': string; + base: string; + }; + 'intense-cherry': { + '100': string; + '200': string; + '300': string; + '400': string; + '500': string; + '600': string; + '700': string; + '800': string; + '900': string; + base: string; + }; + 'vanilla-custard': { + '100': string; + '200': string; + '300': string; + '400': string; + '500': string; + '600': string; + '700': string; + '800': string; + '900': string; + base: string; + }; + 'vanilla-cream': { + '100': string; + '200': string; + '300': string; + '400': string; + '500': string; + '600': string; + '700': string; + '800': string; + '900': string; + base: string; + }; + }; + color: { + yellow: { + '100': string; + '200': string; + '300': string; + '400': string; + '500': string; + '600': string; + '700': string; + '800': string; + '900': string; + base: string; + }; + graphite: { + '100': string; + '200': string; + '300': string; + '400': string; + '500': string; + '600': string; + '700': string; + '800': string; + '900': string; + base: string; + }; + 'intense-cherry': { + '100': string; + '200': string; + '300': string; + '400': string; + '500': string; + '600': string; + '700': string; + '800': string; + '900': string; + base: string; + }; + 'vanilla-custard': { + '100': string; + '200': string; + '300': string; + '400': string; + '500': string; + '600': string; + '700': string; + '800': string; + '900': string; + base: string; + }; + 'vanilla-cream': { + '100': string; + '200': string; + '300': string; + '400': string; + '500': string; + '600': string; + '700': string; + '800': string; + '900': string; + base: string; + }; + primary: { + '100': string; + '200': string; + '300': string; + '400': string; + '500': string; + '600': string; + '700': string; + '800': string; + '900': string; + base: string; + bg: { + hue: string; + lightness: string; + opacity: string; + }; + border: { + hue: string; + lightness: string; + opacity: string; + }; + text: { + hue: string; + lightness: string; + opacity: string; + }; + }; + secondary: { + '100': string; + '200': string; + '300': string; + '400': string; + '500': string; + '600': string; + '700': string; + '800': string; + '900': string; + base: string; + bg: { + hue: string; + lightness: string; + opacity: string; + }; + border: { + hue: string; + lightness: string; + opacity: string; + }; + text: { + hue: string; + lightness: string; + opacity: string; + }; + }; + accent: { + '100': string; + '200': string; + '300': string; + '400': string; + '500': string; + '600': string; + '700': string; + '800': string; + '900': string; + base: string; + }; + neutral: { + '100': string; + '200': string; + '300': string; + '400': string; + '500': string; + '600': string; + '700': string; + '800': string; + '900': string; + base: string; + }; + info: { + '100': string; + '200': string; + '300': string; + '400': string; + '500': string; + '600': string; + '700': string; + '800': string; + '900': string; + }; + bg: { + page: string; + subtle: string; + elevated: string; + inset: string; + primary: string; + 'primary-hover': string; + 'primary-active': string; + 'primary-subtle': string; + accent: string; + 'accent-hover': string; + 'accent-subtle': string; + neutral: string; + 'neutral-strong': string; + info: string; + warning: string; + success: string; + secondary: { + lightness: string; + chroma: string; + hue: string; + opacity: string; + _: string; + }; + danger: { + lightness: string; + chroma: string; + hue: string; + opacity: string; + _: string; + }; + hue: string; + h: string; + lightness: string; + l: string; + opacity: string; + o: string; + }; + text: { + primary: string; + secondary: string; + muted: string; + subtle: string; + link: string; + 'link-hover': string; + info: string; + warning: string; + success: string; + danger: { + lightness: string; + chroma: string; + hue: string; + opacity: string; + _: string; + }; + hue: string; + lightness: string; + opacity: string; + }; + border: { + subtle: string; + default: string; + strong: string; + primary: string; + focus: string; + info: string; + warning: string; + success: string; + neutral: string; + secondary: { + lightness: string; + chroma: string; + hue: string; + opacity: string; + _: string; + }; + danger: { + lightness: string; + chroma: string; + hue: string; + opacity: string; + _: string; + }; + hue: string; + lightness: string; + opacity: string; + }; + feedback: { + error: string; + }; + danger: { + bg: { + hue: string; + lightness: string; + opacity: string; + }; + border: { + hue: string; + lightness: string; + opacity: string; + }; + text: { + hue: string; + lightness: string; + opacity: string; + }; + }; + }; + font: { + scale: { + '0': string; + '1': string; + '2': string; + '3': string; + '4': string; + '5': string; + '6': string; + }; + minFont: string; + maxFont: string; + minViewport: string; + maxViewport: string; + scaleMin: string; + scaleMax: string; + steps: string; + weight: { + light: string; + normal: string; + medium: string; + bold: string; + }; + }; + shadow: { + base: string; + scale: string; + xs: string; + sm: string; + md: string; + lg: string; + xl: string; + }; + space: { + fluid: { + min: string; + max: string; + min_viewport: string; + max_viewport: string; + }; + unit: { + default: string; + fluid: string; + }; + multiplier: { + unit: string; + xxs: string; + xs: string; + sm: string; + md: string; + lg: string; + xl: string; + xxl: string; + }; + }; + layout: { + breakAt: string; + gutter: { + sm: string; + md: string; + lg: string; + xl: string; + }; + direction: string; + align: { + start: string; + center: string; + end: string; + }; + justify: { + start: string; + center: string; + end: string; + between: string; + }; + gap: { + xs: string; + sm: string; + md: string; + lg: string; + xl: string; + }; + overlay: { + zIndex: string; + opacity: string; + blur: string; + }; + spaceUnit: string; + 'depth-base': string; + mobile: { + padding: string; + }; + }; + radius: { + light: string; + medium: string; + heavy: string; + }; + spacing: { + xxs: string; + xs: string; + sm: string; + md: string; + lg: string; + xl: string; + xxl: string; + }; + bg: { + primary: string; + 'primary-hover': string; + 'primary-active': string; + 'primary-focus': string; + 'primary-disable': string; + accent: string; + 'accent-hover': string; + 'accent-active': string; + 'accent-focus': string; + 'accent-disable': string; + neutral: string; + 'neutral-hover': string; + 'neutral-active': string; + 'neutral-focus': string; + 'neutral-disable': string; + info: string; + warning: string; + success: string; + }; + text: { + body: { + size: string; + lineHeight: string; + weight: string; + }; + caption: { + size: string; + lineHeight: string; + weight: string; + }; + small: { + size: string; + lineHeight: string; + weight: string; + }; + }; + heading: { + h1: { + size: string; + lineHeight: string; + weight: string; + }; + h2: { + size: string; + lineHeight: string; + weight: string; + }; + }; + component: { + bg: { + lightness: string; + chroma: string; + hue: string; + opacity: string; + }; + border: { + lightness: string; + chroma: string; + hue: string; + opacity: string; + }; + text: { + lightness: string; + chroma: string; + hue: string; + opacity: string; + }; + opacity: { + bg: string; + border: string; + text: string; + }; + }; + conditional: { + 'not-primary': string; + 'not-secondary': string; + 'not-danger': string; + light: string; + threshold: string; + switch: string; + }; + cube: { + block: { + card: { + bg: string; + border: string; + radius: string; + padding: string; + }; + button: { + paddingX: string; + paddingY: string; + radius: string; + text: string; + bg: string; + 'bg-hover': string; + }; + checkbox: { + bg: string; + padding: string; + }; + }; + composition: { + flow: { + space: string; + }; + stack: { + gap: string; + align: string; + direction: string; + }; + cluster: { + gap: string; + align: string; + }; + center: { + maxWidth: string; + paddingInline: string; + }; + switcher: { + modifier: string; + gap: string; + }; + }; + global: { + gutter: string; + on: string; + off: string; + }; + utility: { + margin: { + 't-0': string; + 't-xs': string; + 't-sm': string; + 't-md': string; + 't-lg': string; + 't-xl': string; + 'b-0': string; + 'b-xs': string; + 'b-sm': string; + 'b-md': string; + 'b-lg': string; + 'b-xl': string; + auto: string; + }; + position: { + relative: string; + absolute: string; + fixed: string; + 'top-0': string; + 'right-0': string; + 'bottom-0': string; + 'left-0': string; + }; + display: { + none: string; + block: string; + 'inline-block': string; + grid: string; + flex: string; + sticky: string; + }; + align: { + start: string; + end: string; + center: string; + }; + justify: { + start: string; + end: string; + center: string; + between: string; + }; + flex: { + column: string; + row: string; + wrap: string; + }; + gap: { + xs: string; + sm: string; + md: string; + lg: string; + xl: string; + }; + padding: { + xs: string; + sm: string; + md: string; + lg: string; + xl: string; + 'x-0': string; + 'x-xs': string; + 'x-sm': string; + 'x-md': string; + 'x-lg': string; + 'x-xl': string; + 'y-0': string; + 'y-xs': string; + 'y-sm': string; + 'y-md': string; + 'y-lg': string; + 'y-xl': string; + auto: string; + 'top-0': string; + 'top-xs': string; + 'top-sm': string; + 'top-md': string; + 'top-lg': string; + 'top-xl': string; + 'bottom-0': string; + }; + text: { + center: string; + dim: string; + }; + border: { + solid: string; + dashed: string; + dotted: string; + none: string; + primary: string; + secondary: string; + accent: string; + neutral: string; + info: string; + success: string; + top: string; + bottom: string; + left: string; + right: string; + all: string; + theme: { + '10': string; + '25': string; + '50': string; + '75': string; + '100': string; + light: string; + medium: string; + large: string; + }; + width: { + xsmall: string; + small: string; + medium: string; + large: string; + }; + }; + radius: { + light: string; + medium: string; + heavy: string; + }; + height: { + auto: string; + full: string; + half: string; + quarter: string; + screen: string; + }; + width: { + auto: string; + full: string; + half: string; + quarter: string; + screen: string; + }; + overflow: { + auto: string; + hidden: string; + scroll: string; + visible: string; + 'x-hidden': string; + 'y-hidden': string; + }; + bg: { + primary: string; + secondary: string; + accent: string; + 'accent-subtle': string; + neutral: string; + page: string; + subtle: string; + elevated: string; + inset: string; + info: string; + success: string; + }; + }; + }; + state: { + base: { + bg: { + lightness: string; + chroma: string; + hue: string; + opacity: string; + }; + border: { + lightness: string; + chroma: string; + hue: string; + opacity: string; + }; + text: { + lightness: string; + chroma: string; + hue: string; + opacity: string; + }; + }; + hover: { + bg: { + lightness: string; + chroma: string; + hue: string; + opacity: string; + }; + border: { + lightness: string; + chroma: string; + hue: string; + opacity: string; + }; + text: { + lightness: string; + chroma: string; + hue: string; + opacity: string; + }; + }; + active: { + bg: { + lightness: string; + chroma: string; + hue: string; + opacity: string; + }; + border: { + lightness: string; + chroma: string; + hue: string; + opacity: string; + }; + text: { + lightness: string; + chroma: string; + hue: string; + opacity: string; + }; + }; + focus: { + bg: { + lightness: string; + chroma: string; + hue: string; + opacity: string; + }; + border: { + lightness: string; + chroma: string; + hue: string; + opacity: string; + }; + text: { + lightness: string; + chroma: string; + hue: string; + opacity: string; + }; + }; + disabled: { + bg: { + lightness: string; + chroma: string; + hue: string; + opacity: string; + }; + border: { + lightness: string; + chroma: string; + hue: string; + opacity: string; + }; + text: { + lightness: string; + chroma: string; + hue: string; + opacity: string; + }; + }; + }; + variant: { + contained: { + bg: { + lightness: string; + chroma: string; + hue: string; + opacity: string; + }; + border: { + lightness: string; + chroma: string; + hue: string; + opacity: string; + }; + text: { + lightness: string; + chroma: string; + hue: string; + opacity: string; + }; + }; + outlined: { + bg: { + lightness: string; + chroma: string; + hue: string; + opacity: string; + }; + border: { + lightness: string; + chroma: string; + hue: string; + opacity: string; + }; + text: { + lightness: string; + chroma: string; + hue: string; + opacity: string; + }; + }; + text: { + bg: { + lightness: string; + chroma: string; + hue: string; + opacity: string; + }; + border: { + lightness: string; + chroma: string; + hue: string; + opacity: string; + }; + text: { + lightness: string; + chroma: string; + hue: string; + opacity: string; + }; + }; + }; + 'highlighted-text': { + gap: { + min: string; + max: string; + scaler: string; + left: string; + }; + }; +} diff --git a/src/assets/css/themes/tokens/types/tokens.ts b/src/assets/css/themes/tokens/types/tokens.ts new file mode 100644 index 00000000..d88f4180 --- /dev/null +++ b/src/assets/css/themes/tokens/types/tokens.ts @@ -0,0 +1,653 @@ +export interface YThemeToken { + 'border-width-base': string; + 'border-width-scale': string; + 'border-width-default': string; + 'border-width-xsmall': string; + 'border-width-small': string; + 'border-width-medium': string; + 'border-width-large': string; + 'border-style-solid': string; + 'border-style-dashed': string; + 'border-style-dotted': string; + 'border-style-double': string; + 'border-style-none': string; + 'border-style-default': string; + 'border-radius-1': string; + 'border-radius-2': string; + 'border-radius-4': string; + 'border-radius-base': string; + 'border-radius-0-5': string; + 'border-radius-scale': string; + 'breakpoint-xs': string; + 'breakpoint-sm': string; + 'breakpoint-md': string; + 'breakpoint-lg': string; + 'breakpoint-xl': string; + 'breakpoint-xxl': string; + 'color-pool-straw-gold-100': string; + 'color-pool-straw-gold-200': string; + 'color-pool-straw-gold-300': string; + 'color-pool-straw-gold-400': string; + 'color-pool-straw-gold-500': string; + 'color-pool-straw-gold-600': string; + 'color-pool-straw-gold-700': string; + 'color-pool-straw-gold-800': string; + 'color-pool-straw-gold-900': string; + 'color-pool-straw-gold-base': string; + 'color-pool-graphite-100': string; + 'color-pool-graphite-200': string; + 'color-pool-graphite-300': string; + 'color-pool-graphite-400': string; + 'color-pool-graphite-500': string; + 'color-pool-graphite-600': string; + 'color-pool-graphite-700': string; + 'color-pool-graphite-800': string; + 'color-pool-graphite-900': string; + 'color-pool-graphite-base': string; + 'color-pool-intense-cherry-100': string; + 'color-pool-intense-cherry-200': string; + 'color-pool-intense-cherry-300': string; + 'color-pool-intense-cherry-400': string; + 'color-pool-intense-cherry-500': string; + 'color-pool-intense-cherry-600': string; + 'color-pool-intense-cherry-700': string; + 'color-pool-intense-cherry-800': string; + 'color-pool-intense-cherry-900': string; + 'color-pool-intense-cherry-base': string; + 'color-pool-vanilla-custard-100': string; + 'color-pool-vanilla-custard-200': string; + 'color-pool-vanilla-custard-300': string; + 'color-pool-vanilla-custard-400': string; + 'color-pool-vanilla-custard-500': string; + 'color-pool-vanilla-custard-600': string; + 'color-pool-vanilla-custard-700': string; + 'color-pool-vanilla-custard-800': string; + 'color-pool-vanilla-custard-900': string; + 'color-pool-vanilla-custard-base': string; + 'color-pool-vanilla-cream-100': string; + 'color-pool-vanilla-cream-200': string; + 'color-pool-vanilla-cream-300': string; + 'color-pool-vanilla-cream-400': string; + 'color-pool-vanilla-cream-500': string; + 'color-pool-vanilla-cream-600': string; + 'color-pool-vanilla-cream-700': string; + 'color-pool-vanilla-cream-800': string; + 'color-pool-vanilla-cream-900': string; + 'color-pool-vanilla-cream-base': string; + 'color-yellow-100': string; + 'color-yellow-200': string; + 'color-yellow-300': string; + 'color-yellow-400': string; + 'color-yellow-500': string; + 'color-yellow-600': string; + 'color-yellow-700': string; + 'color-yellow-800': string; + 'color-yellow-900': string; + 'color-yellow-base': string; + 'color-graphite-100': string; + 'color-graphite-200': string; + 'color-graphite-300': string; + 'color-graphite-400': string; + 'color-graphite-500': string; + 'color-graphite-600': string; + 'color-graphite-700': string; + 'color-graphite-800': string; + 'color-graphite-900': string; + 'color-graphite-base': string; + 'color-intense-cherry-100': string; + 'color-intense-cherry-200': string; + 'color-intense-cherry-300': string; + 'color-intense-cherry-400': string; + 'color-intense-cherry-500': string; + 'color-intense-cherry-600': string; + 'color-intense-cherry-700': string; + 'color-intense-cherry-800': string; + 'color-intense-cherry-900': string; + 'color-intense-cherry-base': string; + 'color-vanilla-custard-100': string; + 'color-vanilla-custard-200': string; + 'color-vanilla-custard-300': string; + 'color-vanilla-custard-400': string; + 'color-vanilla-custard-500': string; + 'color-vanilla-custard-600': string; + 'color-vanilla-custard-700': string; + 'color-vanilla-custard-800': string; + 'color-vanilla-custard-900': string; + 'color-vanilla-custard-base': string; + 'color-vanilla-cream-100': string; + 'color-vanilla-cream-200': string; + 'color-vanilla-cream-300': string; + 'color-vanilla-cream-400': string; + 'color-vanilla-cream-500': string; + 'color-vanilla-cream-600': string; + 'color-vanilla-cream-700': string; + 'color-vanilla-cream-800': string; + 'color-vanilla-cream-900': string; + 'color-vanilla-cream-base': string; + 'color-primary-100': string; + 'color-primary-200': string; + 'color-primary-300': string; + 'color-primary-400': string; + 'color-primary-500': string; + 'color-primary-600': string; + 'color-primary-700': string; + 'color-primary-800': string; + 'color-primary-900': string; + 'color-primary-base': string; + 'color-primary-bg-hue': string; + 'color-primary-bg-lightness': string; + 'color-primary-bg-opacity': string; + 'color-primary-border-hue': string; + 'color-primary-border-lightness': string; + 'color-primary-border-opacity': string; + 'color-primary-text-hue': string; + 'color-primary-text-lightness': string; + 'color-primary-text-opacity': string; + 'color-secondary-100': string; + 'color-secondary-200': string; + 'color-secondary-300': string; + 'color-secondary-400': string; + 'color-secondary-500': string; + 'color-secondary-600': string; + 'color-secondary-700': string; + 'color-secondary-800': string; + 'color-secondary-900': string; + 'color-secondary-base': string; + 'color-secondary-bg-hue': string; + 'color-secondary-bg-lightness': string; + 'color-secondary-bg-opacity': string; + 'color-secondary-border-hue': string; + 'color-secondary-border-lightness': string; + 'color-secondary-border-opacity': string; + 'color-secondary-text-hue': string; + 'color-secondary-text-lightness': string; + 'color-secondary-text-opacity': string; + 'color-accent-100': string; + 'color-accent-200': string; + 'color-accent-300': string; + 'color-accent-400': string; + 'color-accent-500': string; + 'color-accent-600': string; + 'color-accent-700': string; + 'color-accent-800': string; + 'color-accent-900': string; + 'color-accent-base': string; + 'color-neutral-100': string; + 'color-neutral-200': string; + 'color-neutral-300': string; + 'color-neutral-400': string; + 'color-neutral-500': string; + 'color-neutral-600': string; + 'color-neutral-700': string; + 'color-neutral-800': string; + 'color-neutral-900': string; + 'color-neutral-base': string; + 'color-info-100': string; + 'color-info-200': string; + 'color-info-300': string; + 'color-info-400': string; + 'color-info-500': string; + 'color-info-600': string; + 'color-info-700': string; + 'color-info-800': string; + 'color-info-900': string; + 'color-bg-page': string; + 'color-bg-subtle': string; + 'color-bg-elevated': string; + 'color-bg-inset': string; + 'color-bg-primary': string; + 'color-bg-primary-hover': string; + 'color-bg-primary-active': string; + 'color-bg-primary-subtle': string; + 'color-bg-accent': string; + 'color-bg-accent-hover': string; + 'color-bg-accent-subtle': string; + 'color-bg-neutral': string; + 'color-bg-neutral-strong': string; + 'color-bg-info': string; + 'color-bg-warning': string; + 'color-bg-success': string; + 'color-bg-secondary-lightness': string; + 'color-bg-secondary-chroma': string; + 'color-bg-secondary-hue': string; + 'color-bg-secondary-opacity': string; + 'color-bg-secondary': string; + 'color-bg-danger-lightness': string; + 'color-bg-danger-chroma': string; + 'color-bg-danger-hue': string; + 'color-bg-danger-opacity': string; + 'color-bg-danger': string; + 'color-bg-hue': string; + 'color-bg-h': string; + 'color-bg-lightness': string; + 'color-bg-l': string; + 'color-bg-opacity': string; + 'color-bg-o': string; + 'color-text-primary': string; + 'color-text-secondary': string; + 'color-text-muted': string; + 'color-text-subtle': string; + 'color-text-link': string; + 'color-text-link-hover': string; + 'color-text-info': string; + 'color-text-warning': string; + 'color-text-success': string; + 'color-text-danger-lightness': string; + 'color-text-danger-chroma': string; + 'color-text-danger-hue': string; + 'color-text-danger-opacity': string; + 'color-text-danger': string; + 'color-text-hue': string; + 'color-text-lightness': string; + 'color-text-opacity': string; + 'color-border-subtle': string; + 'color-border-default': string; + 'color-border-strong': string; + 'color-border-primary': string; + 'color-border-focus': string; + 'color-border-info': string; + 'color-border-warning': string; + 'color-border-success': string; + 'color-border-neutral': string; + 'color-border-secondary-lightness': string; + 'color-border-secondary-chroma': string; + 'color-border-secondary-hue': string; + 'color-border-secondary-opacity': string; + 'color-border-secondary': string; + 'color-border-danger-lightness': string; + 'color-border-danger-chroma': string; + 'color-border-danger-hue': string; + 'color-border-danger-opacity': string; + 'color-border-danger': string; + 'color-border-hue': string; + 'color-border-lightness': string; + 'color-border-opacity': string; + 'color-feedback-error': string; + 'color-danger-bg-hue': string; + 'color-danger-bg-lightness': string; + 'color-danger-bg-opacity': string; + 'color-danger-border-hue': string; + 'color-danger-border-lightness': string; + 'color-danger-border-opacity': string; + 'color-danger-text-hue': string; + 'color-danger-text-lightness': string; + 'color-danger-text-opacity': string; + 'font-scale-0': string; + 'font-scale-1': string; + 'font-scale-2': string; + 'font-scale-3': string; + 'font-scale-4': string; + 'font-scale-5': string; + 'font-scale-6': string; + 'font-min-font': string; + 'font-max-font': string; + 'font-min-viewport': string; + 'font-max-viewport': string; + 'font-scale-min': string; + 'font-scale-max': string; + 'font-steps': string; + 'font-weight-light': string; + 'font-weight-normal': string; + 'font-weight-medium': string; + 'font-weight-bold': string; + 'shadow-base': string; + 'shadow-scale': string; + 'shadow-xs': string; + 'shadow-sm': string; + 'shadow-md': string; + 'shadow-lg': string; + 'shadow-xl': string; + 'space-fluid-min': string; + 'space-fluid-max': string; + 'space-fluid-min-viewport': string; + 'space-fluid-max-viewport': string; + 'space-unit-default': string; + 'space-unit-fluid': string; + 'space-multiplier-unit': string; + 'space-multiplier-xxs': string; + 'space-multiplier-xs': string; + 'space-multiplier-sm': string; + 'space-multiplier-md': string; + 'space-multiplier-lg': string; + 'space-multiplier-xl': string; + 'space-multiplier-xxl': string; + 'layout-break-at': string; + 'layout-gutter-sm': string; + 'layout-gutter-md': string; + 'layout-gutter-lg': string; + 'layout-gutter-xl': string; + 'layout-direction': string; + 'layout-align-start': string; + 'layout-align-center': string; + 'layout-align-end': string; + 'layout-justify-start': string; + 'layout-justify-center': string; + 'layout-justify-end': string; + 'layout-justify-between': string; + 'layout-gap-xs': string; + 'layout-gap-sm': string; + 'layout-gap-md': string; + 'layout-gap-lg': string; + 'layout-gap-xl': string; + 'layout-overlay-z-index': string; + 'layout-overlay-opacity': string; + 'layout-overlay-blur': string; + 'layout-space-unit': string; + 'layout-depth-base': string; + 'layout-mobile-padding': string; + 'radius-light': string; + 'radius-medium': string; + 'radius-heavy': string; + 'spacing-xxs': string; + 'spacing-xs': string; + 'spacing-sm': string; + 'spacing-md': string; + 'spacing-lg': string; + 'spacing-xl': string; + 'spacing-xxl': string; + 'bg-primary': string; + 'bg-primary-hover': string; + 'bg-primary-active': string; + 'bg-primary-focus': string; + 'bg-primary-disable': string; + 'bg-accent': string; + 'bg-accent-hover': string; + 'bg-accent-active': string; + 'bg-accent-focus': string; + 'bg-accent-disable': string; + 'bg-neutral': string; + 'bg-neutral-hover': string; + 'bg-neutral-active': string; + 'bg-neutral-focus': string; + 'bg-neutral-disable': string; + 'bg-info': string; + 'bg-warning': string; + 'bg-success': string; + 'text-body-size': string; + 'text-body-line-height': string; + 'text-body-weight': string; + 'text-caption-size': string; + 'text-caption-line-height': string; + 'text-caption-weight': string; + 'text-small-size': string; + 'text-small-line-height': string; + 'text-small-weight': string; + 'heading-h1-size': string; + 'heading-h1-line-height': string; + 'heading-h1-weight': string; + 'heading-h2-size': string; + 'heading-h2-line-height': string; + 'heading-h2-weight': string; + 'component-bg-lightness': string; + 'component-bg-chroma': string; + 'component-bg-hue': string; + 'component-bg-opacity': string; + 'component-border-lightness': string; + 'component-border-chroma': string; + 'component-border-hue': string; + 'component-border-opacity': string; + 'component-text-lightness': string; + 'component-text-chroma': string; + 'component-text-hue': string; + 'component-text-opacity': string; + 'component-opacity-bg': string; + 'component-opacity-border': string; + 'component-opacity-text': string; + 'conditional-not-primary': string; + 'conditional-not-secondary': string; + 'conditional-not-danger': string; + 'conditional-light': string; + 'conditional-threshold': string; + 'conditional-switch': string; + 'cube-block-card-bg': string; + 'cube-block-card-border': string; + 'cube-block-card-radius': string; + 'cube-block-card-padding': string; + 'cube-block-button-padding-x': string; + 'cube-block-button-padding-y': string; + 'cube-block-button-radius': string; + 'cube-block-button-text': string; + 'cube-block-button-bg': string; + 'cube-block-button-bg-hover': string; + 'cube-block-checkbox-bg': string; + 'cube-block-checkbox-padding': string; + 'cube-composition-flow-space': string; + 'cube-composition-stack-gap': string; + 'cube-composition-stack-align': string; + 'cube-composition-stack-direction': string; + 'cube-composition-cluster-gap': string; + 'cube-composition-cluster-align': string; + 'cube-composition-center-max-width': string; + 'cube-composition-center-padding-inline': string; + 'cube-composition-switcher-modifier': string; + 'cube-composition-switcher-gap': string; + 'cube-global-gutter': string; + 'cube-global-on': string; + 'cube-global-off': string; + 'cube-utility-margin-t-0': string; + 'cube-utility-margin-t-xs': string; + 'cube-utility-margin-t-sm': string; + 'cube-utility-margin-t-md': string; + 'cube-utility-margin-t-lg': string; + 'cube-utility-margin-t-xl': string; + 'cube-utility-margin-b-0': string; + 'cube-utility-margin-b-xs': string; + 'cube-utility-margin-b-sm': string; + 'cube-utility-margin-b-md': string; + 'cube-utility-margin-b-lg': string; + 'cube-utility-margin-b-xl': string; + 'cube-utility-margin-auto': string; + 'cube-utility-position-relative': string; + 'cube-utility-position-absolute': string; + 'cube-utility-position-fixed': string; + 'cube-utility-position-top-0': string; + 'cube-utility-position-right-0': string; + 'cube-utility-position-bottom-0': string; + 'cube-utility-position-left-0': string; + 'cube-utility-display-none': string; + 'cube-utility-display-block': string; + 'cube-utility-display-inline-block': string; + 'cube-utility-display-grid': string; + 'cube-utility-display-flex': string; + 'cube-utility-display-sticky': string; + 'cube-utility-align-start': string; + 'cube-utility-align-end': string; + 'cube-utility-align-center': string; + 'cube-utility-justify-start': string; + 'cube-utility-justify-end': string; + 'cube-utility-justify-center': string; + 'cube-utility-justify-between': string; + 'cube-utility-flex-column': string; + 'cube-utility-flex-row': string; + 'cube-utility-flex-wrap': string; + 'cube-utility-gap-xs': string; + 'cube-utility-gap-sm': string; + 'cube-utility-gap-md': string; + 'cube-utility-gap-lg': string; + 'cube-utility-gap-xl': string; + 'cube-utility-padding-xs': string; + 'cube-utility-padding-sm': string; + 'cube-utility-padding-md': string; + 'cube-utility-padding-lg': string; + 'cube-utility-padding-xl': string; + 'cube-utility-padding-x-0': string; + 'cube-utility-padding-x-xs': string; + 'cube-utility-padding-x-sm': string; + 'cube-utility-padding-x-md': string; + 'cube-utility-padding-x-lg': string; + 'cube-utility-padding-x-xl': string; + 'cube-utility-padding-y-0': string; + 'cube-utility-padding-y-xs': string; + 'cube-utility-padding-y-sm': string; + 'cube-utility-padding-y-md': string; + 'cube-utility-padding-y-lg': string; + 'cube-utility-padding-y-xl': string; + 'cube-utility-padding-auto': string; + 'cube-utility-padding-top-0': string; + 'cube-utility-padding-top-xs': string; + 'cube-utility-padding-top-sm': string; + 'cube-utility-padding-top-md': string; + 'cube-utility-padding-top-lg': string; + 'cube-utility-padding-top-xl': string; + 'cube-utility-padding-bottom-0': string; + 'cube-utility-text-center': string; + 'cube-utility-text-dim': string; + 'cube-utility-border-solid': string; + 'cube-utility-border-dashed': string; + 'cube-utility-border-dotted': string; + 'cube-utility-border-none': string; + 'cube-utility-border-primary': string; + 'cube-utility-border-secondary': string; + 'cube-utility-border-accent': string; + 'cube-utility-border-neutral': string; + 'cube-utility-border-info': string; + 'cube-utility-border-success': string; + 'cube-utility-border-top': string; + 'cube-utility-border-bottom': string; + 'cube-utility-border-left': string; + 'cube-utility-border-right': string; + 'cube-utility-border-all': string; + 'cube-utility-border-theme-10': string; + 'cube-utility-border-theme-25': string; + 'cube-utility-border-theme-50': string; + 'cube-utility-border-theme-75': string; + 'cube-utility-border-theme-100': string; + 'cube-utility-border-theme-light': string; + 'cube-utility-border-theme-medium': string; + 'cube-utility-border-theme-large': string; + 'cube-utility-border-width-xsmall': string; + 'cube-utility-border-width-small': string; + 'cube-utility-border-width-medium': string; + 'cube-utility-border-width-large': string; + 'cube-utility-radius-light': string; + 'cube-utility-radius-medium': string; + 'cube-utility-radius-heavy': string; + 'cube-utility-height-auto': string; + 'cube-utility-height-full': string; + 'cube-utility-height-half': string; + 'cube-utility-height-quarter': string; + 'cube-utility-height-screen': string; + 'cube-utility-width-auto': string; + 'cube-utility-width-full': string; + 'cube-utility-width-half': string; + 'cube-utility-width-quarter': string; + 'cube-utility-width-screen': string; + 'cube-utility-overflow-auto': string; + 'cube-utility-overflow-hidden': string; + 'cube-utility-overflow-scroll': string; + 'cube-utility-overflow-visible': string; + 'cube-utility-overflow-x-hidden': string; + 'cube-utility-overflow-y-hidden': string; + 'cube-utility-bg-primary': string; + 'cube-utility-bg-secondary': string; + 'cube-utility-bg-accent': string; + 'cube-utility-bg-accent-subtle': string; + 'cube-utility-bg-neutral': string; + 'cube-utility-bg-page': string; + 'cube-utility-bg-subtle': string; + 'cube-utility-bg-elevated': string; + 'cube-utility-bg-inset': string; + 'cube-utility-bg-info': string; + 'cube-utility-bg-success': string; + 'state-base-bg-lightness': string; + 'state-base-bg-chroma': string; + 'state-base-bg-hue': string; + 'state-base-bg-opacity': string; + 'state-base-border-lightness': string; + 'state-base-border-chroma': string; + 'state-base-border-hue': string; + 'state-base-border-opacity': string; + 'state-base-text-lightness': string; + 'state-base-text-chroma': string; + 'state-base-text-hue': string; + 'state-base-text-opacity': string; + 'state-hover-bg-lightness': string; + 'state-hover-bg-chroma': string; + 'state-hover-bg-hue': string; + 'state-hover-bg-opacity': string; + 'state-hover-border-lightness': string; + 'state-hover-border-chroma': string; + 'state-hover-border-hue': string; + 'state-hover-border-opacity': string; + 'state-hover-text-lightness': string; + 'state-hover-text-chroma': string; + 'state-hover-text-hue': string; + 'state-hover-text-opacity': string; + 'state-active-bg-lightness': string; + 'state-active-bg-chroma': string; + 'state-active-bg-hue': string; + 'state-active-bg-opacity': string; + 'state-active-border-lightness': string; + 'state-active-border-chroma': string; + 'state-active-border-hue': string; + 'state-active-border-opacity': string; + 'state-active-text-lightness': string; + 'state-active-text-chroma': string; + 'state-active-text-hue': string; + 'state-active-text-opacity': string; + 'state-focus-bg-lightness': string; + 'state-focus-bg-chroma': string; + 'state-focus-bg-hue': string; + 'state-focus-bg-opacity': string; + 'state-focus-border-lightness': string; + 'state-focus-border-chroma': string; + 'state-focus-border-hue': string; + 'state-focus-border-opacity': string; + 'state-focus-text-lightness': string; + 'state-focus-text-chroma': string; + 'state-focus-text-hue': string; + 'state-focus-text-opacity': string; + 'state-disabled-bg-lightness': string; + 'state-disabled-bg-chroma': string; + 'state-disabled-bg-hue': string; + 'state-disabled-bg-opacity': string; + 'state-disabled-border-lightness': string; + 'state-disabled-border-chroma': string; + 'state-disabled-border-hue': string; + 'state-disabled-border-opacity': string; + 'state-disabled-text-lightness': string; + 'state-disabled-text-chroma': string; + 'state-disabled-text-hue': string; + 'state-disabled-text-opacity': string; + 'variant-contained-bg-lightness': string; + 'variant-contained-bg-chroma': string; + 'variant-contained-bg-hue': string; + 'variant-contained-bg-opacity': string; + 'variant-contained-border-lightness': string; + 'variant-contained-border-chroma': string; + 'variant-contained-border-hue': string; + 'variant-contained-border-opacity': string; + 'variant-contained-text-lightness': string; + 'variant-contained-text-chroma': string; + 'variant-contained-text-hue': string; + 'variant-contained-text-opacity': string; + 'variant-outlined-bg-lightness': string; + 'variant-outlined-bg-chroma': string; + 'variant-outlined-bg-hue': string; + 'variant-outlined-bg-opacity': string; + 'variant-outlined-border-lightness': string; + 'variant-outlined-border-chroma': string; + 'variant-outlined-border-hue': string; + 'variant-outlined-border-opacity': string; + 'variant-outlined-text-lightness': string; + 'variant-outlined-text-chroma': string; + 'variant-outlined-text-hue': string; + 'variant-outlined-text-opacity': string; + 'variant-text-bg-lightness': string; + 'variant-text-bg-chroma': string; + 'variant-text-bg-hue': string; + 'variant-text-bg-opacity': string; + 'variant-text-border-lightness': string; + 'variant-text-border-chroma': string; + 'variant-text-border-hue': string; + 'variant-text-border-opacity': string; + 'variant-text-text-lightness': string; + 'variant-text-text-chroma': string; + 'variant-text-text-hue': string; + 'variant-text-text-opacity': string; + 'highlighted-text-gap-min': string; + 'highlighted-text-gap-max': string; + 'highlighted-text-gap-scaler': string; + 'highlighted-text-gap-left': string; + +} diff --git a/src/assets/css/themes/tone.css b/src/assets/css/themes/tone.css new file mode 100644 index 00000000..1bbaaf2e --- /dev/null +++ b/src/assets/css/themes/tone.css @@ -0,0 +1,107 @@ +/* tone.css */ +@layer props, api, engine; + +/* ----------------------------------------------------------------------------- + * PROPS (ONLY @property) + * -------------------------------------------------------------------------- */ +@layer props { + /* prettier-ignore */ + @property --tone { syntax: "primary | secondary | danger"; initial-value: primary; inherits: true; } + + /* token-or-0 (else-0) */ + + /* prettier-ignore */ + @property --_tone-primary-else-0 { syntax: "primary | "; initial-value: 0; inherits: true; } + + /* prettier-ignore */ + @property --_tone-secondary-else-0 { syntax: "secondary | "; initial-value: 0; inherits: true; } + + /* prettier-ignore */ + @property --_tone-danger-else-0 { syntax: "danger | "; initial-value: 0; inherits: true; } + + /* bits (invalid => initial-value 1) */ + + /* prettier-ignore */ + @property --is-tone-primary { syntax: ""; initial-value: 1; inherits: true; } + + /* prettier-ignore */ + @property --is-tone-secondary { syntax: ""; initial-value: 1; inherits: true; } + + /* prettier-ignore */ + @property --is-tone-danger { syntax: ""; initial-value: 1; inherits: true; } +} + +/* ----------------------------------------------------------------------------- + * API (classes only set the enum) + * -------------------------------------------------------------------------- */ +@layer api { + .primary { + --tone: primary; + } + + .secondary { + --tone: secondary; + } + + .danger { + --tone: danger; + } +} + +/* ----------------------------------------------------------------------------- + * ENGINE (grind -> bits, then map -> tone-l/c/h/a) + * -------------------------------------------------------------------------- */ +@layer engine { + [data-compose-ui] { + /** + * 1) Grind tone enum into bits + * - if --tone matches keyword => else-0 becomes keyword, bit becomes 1 (fallback) + * - else => else-0 becomes 0, bit becomes 0 + */ + --_tone-primary-else-0: var(--tone); + --is-tone-primary: var(--_tone-primary-else-0); + --_tone-secondary-else-0: var(--tone); + --is-tone-secondary: var(--_tone-secondary-else-0); + --_tone-danger-else-0: var(--tone); + --is-tone-danger: var(--_tone-danger-else-0); + + /** + * 2) Map intent tokens -> selected tone channels (oklch components) + * Uses your existing token names (primitive/semantic/intent can feed these) + */ + + /* prettier-ignore */ + --tone-l: calc( + var(--is-tone-primary) * var(--color-primary-lightness) + + var(--is-tone-secondary) * var(--color-secondary-lightness) + + var(--is-tone-danger) * var(--color-danger-lightness) + ); + + /* prettier-ignore */ + --tone-c: calc( + var(--is-tone-primary) * var(--color-primary-chroma) + + var(--is-tone-secondary) * var(--color-secondary-chroma) + + var(--is-tone-danger) * var(--color-danger-chroma) + ); + + /* prettier-ignore */ + --tone-h: calc( + var(--is-tone-primary) * var(--color-primary-hue) + + var(--is-tone-secondary) * var(--color-secondary-hue) + + var(--is-tone-danger) * var(--color-danger-hue) + ); + + /* prettier-ignore */ + --tone-a: calc( + var(--is-tone-primary) * var(--color-primary-opacity) + + var(--is-tone-secondary) * var(--color-secondary-opacity) + + var(--is-tone-danger) * var(--color-danger-opacity) + ); + + /** + * Optional: keep an actual color version if you still want it + * (useful for shadows/mix, though you already render via oklch later) + */ + --theme-current-color: oklch(var(--tone-l) var(--tone-c) var(--tone-h) / var(--tone-a)); + } +} diff --git a/src/assets/css/tokens/css/cube/cube.composition.css b/src/assets/css/tokens/css/cube/cube.composition.css deleted file mode 100644 index 1a2bffb4..00000000 --- a/src/assets/css/tokens/css/cube/cube.composition.css +++ /dev/null @@ -1,16 +0,0 @@ -/** - * Do not edit directly, this file was auto-generated. - */ - -:root { - --cube-composition-flow-space: var(--_layout-gutter-md); - --cube-composition-stack-gap: var(--_layout-gutter-md); - --cube-composition-stack-align: start; - --cube-composition-stack-direction: var(--__layout-direction, column); - --cube-composition-cluster-gap: var(--_layout-gutter-sm); - --cube-composition-cluster-align: center; - --cube-composition-center-max-width: 72ch; - --cube-composition-center-padding-inline: var(--_layout-gutter-md); - --cube-composition-switcher-modifier: var(--__layout-break-at); - --cube-composition-switcher-gap: var(--_layout-gutter-sm); -} diff --git a/src/assets/css/tokens/css/cube/cube.utility.css b/src/assets/css/tokens/css/cube/cube.utility.css deleted file mode 100644 index 845e80a6..00000000 --- a/src/assets/css/tokens/css/cube/cube.utility.css +++ /dev/null @@ -1,131 +0,0 @@ - -/* ------------------------------------------------------------ */ -/* Margin */ -/* ------------------------------------------------------------ */ -.margin-t-0 { margin-block-start: 0 } -.margin-t-xs { margin-block-start: var(--_spacing-xs) } -.margin-t-sm { margin-block-start: var(--_spacing-sm) } -.margin-t-md { margin-block-end: var(--_spacing-md) } -.margin-t-lg { margin-block-end: var(--_spacing-lg) } -.margin-t-xl { margin-block-start: var(--_spacing-xl) } -.margin-b-0 { margin-block-end: 0 } -.margin-b-xs { margin-block-end: var(--_spacing-xs) } -.margin-b-sm { margin-block-end: var(--_spacing-sm) } -.margin-b-md { margin-block-end: var(--_spacing-md) } -.margin-b-lg { margin-block-end: var(--_spacing-lg) } -.margin-b-xl { margin-block-end: var(--_spacing-xl) } -.margin-auto { margin: auto } - -/* ------------------------------------------------------------ */ -/* Position */ -/* ------------------------------------------------------------ */ -.position-relative { position: relative } -.position-absolute { position: absolute } -.position-fixed { position: fixed } -.position-top-0 { top: 0 } -.position-right-0 { right: 0 } -.position-bottom-0 { bottom: 0 } -.position-left-0 { left: 0 } - -/* ------------------------------------------------------------ */ -/* Display */ -/* ------------------------------------------------------------ */ -.none { display: none } -.block { display: block } -.inline-block { display: inline-block } -.grid { display: grid } -.flex { display: flex } -.sticky { position: sticky } - -/* ------------------------------------------------------------ */ -/* Align */ -/* ------------------------------------------------------------ */ -.align-start { --_layout-align: flex-start } -.align-end { --_layout-align: flex-end } -.align-center { --_layout-align: center } - -/* ------------------------------------------------------------ */ -/* Justify */ -/* ------------------------------------------------------------ */ -.justify-start { --_layout-justify: flex-start } -.justify-end { --_layout-justify: flex-end } -.justify-center { --_layout-justify: center } -.justify-between { --_layout-justify: space-between } - -/* ------------------------------------------------------------ */ -/* Flex */ -/* ------------------------------------------------------------ */ -.flex-column { --_layout-direction: column } -.flex-row { --_layout-direction: row } -.flex-wrap { flex-wrap: wrap } - -/* ------------------------------------------------------------ */ -/* Gap */ -/* ------------------------------------------------------------ */ -.gap-xs { gap: var(--_spacing-xs) } -.gap-sm { gap: var(--_spacing-sm) } -.gap-md { gap: var(--_spacing-md) } -.gap-lg { gap: var(--_spacing-lg) } -.gap-xl { gap: var(--_spacing-xl) } - -/* ------------------------------------------------------------ */ -/* Padding */ -/* ------------------------------------------------------------ */ -.padding-xs { padding: var(--_spacing-xs) } -.padding-sm { padding: var(--_spacing-sm) } -.padding-md { padding: var(--_spacing-md) } -.padding-lg { padding: var(--_spacing-lg) } -.padding-xl { padding: var(--_spacing-xl) } -.padding-x-0 { padding-inline: 0 } -.padding-x-sm { padding-inline: var(--_spacing-sm) } -.padding-y-md { padding-block: var(--_spacing-md) } - -/* ------------------------------------------------------------ */ -/* Text */ -/* ------------------------------------------------------------ */ -.text-center { text-align: center } -.text-dim { opacity: 0.7 } - -/* ------------------------------------------------------------ */ -/* Border */ -/* ------------------------------------------------------------ */ -.border-top { border-top: var(--_border-width-default) solid var(--_theme-color) } -.border-bottom { border-bottom: var(--_border-width-default) solid var(--_theme-color) } -.border-left { border-left: var(--_border-width-default) solid var(--_theme-color) } -.border-right { border-right: var(--_border-width-default) solid var(--_theme-color) } -.border-all { border: var(--_border-width-default) solid var(--_theme-color) } -.border-theme-10 { border: var(--_border-width-10) solid var(--_theme-color) } -.border-theme-25 { border: var(--_border-width-25) solid var(--_theme-color) } -.border-theme-50 { border: var(--_border-width-50) solid var(--_theme-color) } -.border-theme-75 { border: var(--_border-width-75) solid var(--_theme-color) } -.border-theme-100 { border: var(--_border-width-100) solid var(--_theme-color) } -.border-theme-light { border: var(--_border-width-small) solid var(--_theme-color) } -.border-theme-medium { border: var(--_border-width-medium) solid var(--_theme-color) } -.border-theme-heavy { border: var(--_border-width-heavy) solid var(--_theme-color) } -.border-width-10 { border-width: var(--_border-width-10) } -.border-width-25 { border-width: var(--_border-width-25) } -.border-width-50 { border-width: var(--_border-width-50) } -.border-width-75 { border-width: var(--_border-width-75) } - -/* ------------------------------------------------------------ */ -/* Radius */ -/* ------------------------------------------------------------ */ -.radius-light { border-radius: var(--_border-radius-light) } -.radius-medium { border-radius: var(--_border-radius-medium) } -.radius-heavy { border-radius: var(--_border-radius-heavy) } - -/* ------------------------------------------------------------ */ -/* Height */ -/* ------------------------------------------------------------ */ -.height-auto { height: auto } -.height-full { height: 100% } -.height-half { height: 50% } -.height-screen { height: 100svh } - -/* ------------------------------------------------------------ */ -/* Width */ -/* ------------------------------------------------------------ */ -.width-auto { width: auto } -.width-full { width: 100% } -.width-half { width: 50% } -.width-screen { width: 100svw } diff --git a/src/assets/css/utils/layout.css b/src/assets/css/utils/layout.css index 746b476c..0af56f48 100644 --- a/src/assets/css/utils/layout.css +++ b/src/assets/css/utils/layout.css @@ -6,12 +6,14 @@ display: flex; flex-wrap: wrap; gap: var(--gap, 1rem); + --switch: 40rem; } .holy > * { flex-grow: 1; flex-basis: calc((var(--switch) - 100%) * 999); + /* avoid overflow from long content */ min-width: 0; } diff --git a/src/assets/css/utils/media.css b/src/assets/css/utils/media.css new file mode 100644 index 00000000..656fbee5 --- /dev/null +++ b/src/assets/css/utils/media.css @@ -0,0 +1,44 @@ +/* + * https://github.com/propjockey/css-media-vars + */ + +:root { + --media-xs: var(--on); + --media-sm: var(--on); + --media-md: var(--on); + --media-lg: var(--on); + --media-xl: var(--on); +} + +/* @media (min-width: 0px) { + :root { + --is-screen-xs: ; + } +} */ + +/* sm+ */ +@media (width >= 40rem) { + :root { + --media-sm: var(--off); + } +} + +/* md+ */ +@media (width >= 64rem) { + :root { + --media-md: var(--off); + } +} + +/* lg+ */ +@media (width >= 80rem) { + :root { + --media-lg: var(--off); + } +} + +@media (width >= 90rem) { + :root { + --media-xl: var(--off); + } +} diff --git a/src/assets/css/utils/viewport.css b/src/assets/css/utils/viewport.css index 431b25e7..9681e66c 100644 --- a/src/assets/css/utils/viewport.css +++ b/src/assets/css/utils/viewport.css @@ -4,12 +4,13 @@ */ @property --100vw { syntax: ''; - initial-value: 0px; + initial-value: 0; inherits: false; } + @property --100vh { syntax: ''; - initial-value: 0px; + initial-value: 0; inherits: false; } @@ -18,6 +19,7 @@ --100vh: 100vh; --viewport-width: calc(tan(atan2(var(--100vw), 1px))); --viewport-height: calc(tan(atan2(var(--100vh), 1px))); + /* calc() wrapper required for Safari, bug: // https://bugs.webkit.org/show_bug.cgi?id=263000 */ diff --git a/src/assets/scss/global.scss b/src/assets/scss/global.scss index 80adfcc0..51f05044 100644 --- a/src/assets/scss/global.scss +++ b/src/assets/scss/global.scss @@ -246,6 +246,7 @@ $variants: ('contained', 'outlined', 'text'); @mixin theme-component { padding: utils.component(padding-y) utils.component(padding-x); + // margin: 0 utils.component(margin-x) 0 utils.component(margin-bottom); // box-shadow: utils.component(box-shadow); outline: none; @@ -308,12 +309,15 @@ $variants: ('contained', 'outlined', 'text'); // } // &.primary { @include theme.primary; + // } // &.secondary { @include theme.secondary; + // } // &.danger { @include theme.danger; + // } // State Props @@ -322,11 +326,11 @@ $variants: ('contained', 'outlined', 'text'); // } // &:hover, - // &.hover { - &:not([disabled], .disabled, :disabled) { - @include theme.base; - @include theme.hover; - } + // // &.hover { + // &:not([disabled], .disabled, :disabled) { + // @include theme.base; + // @include theme.hover; + // } // } // } @@ -334,17 +338,21 @@ $variants: ('contained', 'outlined', 'text'); // &.disabled, // &[disabled] { @include theme.disabled; + // } // Variant Props // &.contained { @include theme.contained; + // } // &.outlined { @include theme.outlined; + // } // &.text { @include theme.text; + // } // Prevent non-interactive component to have an effect on click or keyboard focus // &:active, @@ -442,11 +450,13 @@ $variants: ('contained', 'outlined', 'text'); // &:focus-visible { &:not([disabled], .disabled, :disabled) { @include theme.focus; + // } // &:active, // &.active { @include theme.active; } + // } // } } diff --git a/src/assets/scss/theme.scss b/src/assets/scss/theme.scss index 4c351d78..9d2ddc48 100644 --- a/src/assets/scss/theme.scss +++ b/src/assets/scss/theme.scss @@ -246,9 +246,11 @@ $variants: ('contained', 'outlined', 'text'); @mixin theme-component { padding: utils.component(padding-y) utils.component(padding-x); + // margin: 0 utils.component(margin-x) 0 utils.component(margin-bottom); // box-shadow: utils.component(box-shadow); outline: none; + // transform: utils.component(transform); transition: utils.component(transition); @@ -308,12 +310,15 @@ $variants: ('contained', 'outlined', 'text'); // } // &.primary { @include theme.primary; + // } // &.secondary { @include theme.secondary; + // } // &.danger { @include theme.danger; + // } // State Props @@ -327,6 +332,7 @@ $variants: ('contained', 'outlined', 'text'); @include theme.base; @include theme.hover; } + // } // } @@ -334,17 +340,21 @@ $variants: ('contained', 'outlined', 'text'); // &.disabled, // &[disabled] { @include theme.disabled; + // } // Variant Props // &.contained { @include theme.contained; + // } // &.outlined { @include theme.outlined; + // } // &.text { @include theme.text; + // } // Prevent non-interactive component to have an effect on click or keyboard focus // &:active, @@ -442,11 +452,13 @@ $variants: ('contained', 'outlined', 'text'); // &:focus-visible { &:not([disabled], .disabled, :disabled) { @include theme.focus; + // } // &:active, // &.active { @include theme.active; } + // } // } } diff --git a/src/assets/scss/theme/_state.scss b/src/assets/scss/theme/_state.scss index b055a25c..bbf58803 100644 --- a/src/assets/scss/theme/_state.scss +++ b/src/assets/scss/theme/_state.scss @@ -7,6 +7,7 @@ bg-lightness, calc(var(--state-base-bg-lightness) - var(--state-#{$state}-bg-lightness)) ); + // @include utils.component(box-shadow, utils.component(box-shadow-#{$state})); &:not(.raw) { @@ -33,6 +34,7 @@ @content; } + // } } @@ -45,6 +47,7 @@ @include resolve-state(focus); @content; } + // } } @@ -56,6 +59,7 @@ @content; } + // } } diff --git a/src/assets/scss/theme/_theme copy.scss b/src/assets/scss/theme/_theme copy.scss index e3a05e98..7efa3ca4 100644 --- a/src/assets/scss/theme/_theme copy.scss +++ b/src/assets/scss/theme/_theme copy.scss @@ -83,9 +83,11 @@ $VARIANTS: ( @mixin focus-visual() { @include colors.focus; } + @mixin active-visual() { @include colors.active; } + @mixin disabled-visual() { @include colors.disabled; } @@ -113,12 +115,15 @@ $VARIANTS: ( @include state.hover { @include apply-props(map.get($def, hover)); } + @include state.focus { @include apply-props(map.get($def, focus)); } + @include state.active { @include apply-props(map.get($def, active)); } + @include state.disabled { @include apply-props(map.get($def, disabled)); } @@ -154,19 +159,19 @@ $VARIANTS: ( &.focus, &:focus-visible { @include mixins.resolve-lch-value('state', focus); - @include focus-visual(); + @include focus-visual; } &:active, &.active { @include mixins.resolve-lch-value('state', active); - @include active-visual(); + @include active-visual; } } &.disabled, &[disabled] { - @include disabled-visual(); + @include disabled-visual; } } @@ -183,14 +188,17 @@ $VARIANTS: ( &.base { /* no-op placeholder if you rely on it */ } + &.hover { @include state.hover { } } + &.focus { @include state.focus { } } + &.active { @include state.active { } diff --git a/src/assets/scss/theme/_theme.scss b/src/assets/scss/theme/_theme.scss index b3b0ee3c..b55ca489 100644 --- a/src/assets/scss/theme/_theme.scss +++ b/src/assets/scss/theme/_theme.scss @@ -1,4 +1,5 @@ @forward 'variant'; @forward 'state'; @forward 'color'; + // @forward './theme copy'; diff --git a/src/assets/scss/theme/_variant.scss b/src/assets/scss/theme/_variant.scss index 05322a17..1065f62e 100644 --- a/src/assets/scss/theme/_variant.scss +++ b/src/assets/scss/theme/_variant.scss @@ -16,8 +16,10 @@ @include mixins.resolve-lch-value('variant', outlined); @include mixins.component(border-style, solid); @include mixins.component(border-color, var(--theme-current-color)); + // @include mixins.component(color-text, var(--theme-current-color)); @include mixins.component(bg-opacity, var(--variant-bg-opacity)); + // @include mixins.component(bg-opacity, var(--state-base-bg-opacity)); @include state.active { @@ -27,6 +29,7 @@ [data-state='disabled'] & { // @include mixins.component(bg-opacity, var(--state-disabled-bg-lightness)); } + // @include state.disabled { // @include mixins.component(bg-opacity, var(--state-disabled-bg-lightness)); // } diff --git a/src/components/ComponentDocs/ComponentDocs.vue b/src/components/ComponentDocs/ComponentDocs.vue index c8c54d87..4ac54acb 100644 --- a/src/components/ComponentDocs/ComponentDocs.vue +++ b/src/components/ComponentDocs/ComponentDocs.vue @@ -1,13 +1,13 @@ diff --git a/src/components/YBox/__snapshots__/YBox.test.ts.snap b/src/components/YBox/__snapshots__/YBox.test.ts.snap new file mode 100644 index 00000000..cbd25e60 --- /dev/null +++ b/src/components/YBox/__snapshots__/YBox.test.ts.snap @@ -0,0 +1,3 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`YBox > renders 1`] = `"
"`; diff --git a/src/components/YBox/index.ts b/src/components/YBox/index.ts new file mode 100644 index 00000000..17ca6e99 --- /dev/null +++ b/src/components/YBox/index.ts @@ -0,0 +1 @@ +export { default as YBox } from './YBox.vue' \ No newline at end of file diff --git a/src/components/YButton/YButton.css b/src/components/YButton/YButton.css index dd99c05c..d0df18af 100644 --- a/src/components/YButton/YButton.css +++ b/src/components/YButton/YButton.css @@ -2,7 +2,8 @@ display: inline-block; text-transform: uppercase; cursor: pointer; - --component-padding: var(--_spacing-sm) var(--_spacing-md); + + --component-padding: var(--_spacing-md) var(--_spacing-sm); &:focus, &:focus-visible, diff --git a/src/components/YCheckbox/YCheckbox.css b/src/components/YCheckbox/YCheckbox.css index 817989fa..6d36225f 100644 --- a/src/components/YCheckbox/YCheckbox.css +++ b/src/components/YCheckbox/YCheckbox.css @@ -1,5 +1,6 @@ /* Needed for the animation /* https://css-tricks.com/exploring-property-and-its-animating-powers/ */ + /* @property --transform-scale { syntax: ''; inherits: false; @@ -23,7 +24,7 @@ padding: var(--_checkbox-padding, var(--spacing-xs)); border-radius: var(--_checkbox-radius, var(--border-radius-medium)); - &:before { + &::before { content: ''; position: absolute; width: 70%; @@ -35,9 +36,11 @@ /* border: var(--border-theme-50); */ background-color: var(--_checkbox-bg, var(--color-bg-primary)); box-sizing: border-box; + /* transform: translate(var(--_checkbox-checkmark-translate)) scale(var(--transform-scale)); */ transform: translate(-50%, -50%) scale(0); + /* animation: var(--checkbox-animation); */ transition: transform 200ms ease, @@ -47,31 +50,14 @@ &:checked { /* --checkbox-animation: var(--checkbox-animation-checked-in); */ - &:before { + &::before { transform: translate(-50%, -50%) scale(1); background-color: var(--color-main-dark); } } - &:not(:checked) { - /* --y-checkbox-animation: var(--animate-checked-out); */ - } &:active, &:focus { --state-bg-lightness: var(--state-hover-bg-lightness); } } -/* -.y-checkbox-wrapper .y-checkbox { - --animate-checked-in: checked-in 0.3s 0s forwards; - --animate-checked-out: var(--has-changed-once, checked-out 0.3s 0s forwards); -} - -.y-checkbox-wrapper:has(.y-checkbox:checked), -.y-checkbox-wrapper:has(.y-checkbox:checked) .y-checkbox { - --y-checkbox-animation: var(--animate-checked-in); -} - -.y-checkbox-wrapper:has(.y-checkbox:not(:checked)) .y-checkbox { - --y-checkbox-animation: var(--animate-checked-out); -} */ diff --git a/src/components/YContainer/YContainer.css b/src/components/YContainer/YContainer.css index 0ec61d28..15b9a77b 100644 --- a/src/components/YContainer/YContainer.css +++ b/src/components/YContainer/YContainer.css @@ -1,12 +1,15 @@ +/* https://grafikart.fr/tutoriels/conteneur-css-1233 */ .y-container { - max-width: 640px; - padding: 0 var(--_spacing-units, 1rem); + box-sizing: border-box; + width: min(var(--breakpoint-sm), calc(100% - 4 * var(--layout-mobile-padding))); + margin-inline: auto; &.fluid { width: 100%; } } +/* @media (min-width: 768px) { .y-container { max-width: 768px; @@ -29,4 +32,4 @@ .y-container { max-width: 1820px; } -} +} */ diff --git a/src/components/YFlex/YFlex.vue b/src/components/YFlex/YFlex.vue index 37209949..4403badf 100644 --- a/src/components/YFlex/YFlex.vue +++ b/src/components/YFlex/YFlex.vue @@ -1,11 +1,12 @@ diff --git a/src/components/YFlow/__snapshots__/YFlow.test.ts.snap b/src/components/YFlow/__snapshots__/YFlow.test.ts.snap new file mode 100644 index 00000000..33a538e0 --- /dev/null +++ b/src/components/YFlow/__snapshots__/YFlow.test.ts.snap @@ -0,0 +1,7 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`YFlow > renders 1`] = ` +"
+

Default content for YFlow component

+
" +`; diff --git a/src/components/YFlow/index.ts b/src/components/YFlow/index.ts new file mode 100644 index 00000000..2441d034 --- /dev/null +++ b/src/components/YFlow/index.ts @@ -0,0 +1 @@ +export { default as YFlow } from './YFlow.vue' \ No newline at end of file diff --git a/src/components/YHeader/YHeader.css b/src/components/YHeader/YHeader.css index 6c2a895c..6c1e1e73 100644 --- a/src/components/YHeader/YHeader.css +++ b/src/components/YHeader/YHeader.css @@ -24,13 +24,13 @@ } } -@media (min-width: 768px) { +@media (width >= 768px) { .y-header { height: var(--header-md); } } -@media (min-width: 1024px) { +@media (width >= 1024px) { .y-header { height: var(--header-lg); } diff --git a/src/components/YHighlightedText/YHighlightedText.css b/src/components/YHighlightedText/YHighlightedText.css index a7dd9d7b..9697b615 100644 --- a/src/components/YHighlightedText/YHighlightedText.css +++ b/src/components/YHighlightedText/YHighlightedText.css @@ -1,4 +1,5 @@ /* https://stackoverflow.com/questions/6542212/use-css3-transitions-with-gradient-backgrounds/63848864#63848864 */ + /* Used for the shake animation see shake.css */ @property --highlighted-color-1 { syntax: ''; @@ -13,6 +14,7 @@ } /* Control wether the highlighted background is displayed by default */ + /* Used with animation */ @property --active { syntax: ''; @@ -20,47 +22,32 @@ inherits: true; } -h1.-highlighted, -h2.-highlighted, -h3.-highlighted, -h4.-highlighted, -.h1.-highlighted, -.text-xxl.-highlighted, -.text-xl.-highlighted, -.text-lg.-highlighted, -.text-md.-highlighted, -.text-sm.-highlighted, -.text-xs.-highlighted, -p.-highlighted, -span.-highlighted, -*.-highlighted { - /* // --highlighted-bg-color: color-mix( - // in srgb, - // var(--color-bg), - // var(--theme-current-color) calc(100% * var(--active, 0)) - // ); */ - --highlighted-bg-color-1: var(--highlighted-bg-color); - --highlighted-bg-color-2: var(--highlighted-bg-color); - +.-highlighted { text-transform: uppercase; + /* TODO: check responsive line-height */ line-height: 135%; margin: 0; position: relative; + --is-not-hovered-yet: ; + /* // line-height: 135%; */ + /* // margin: 0; */ + /* // padding: 4px 10px 1.4px; */ &.stick-to-left { /* // position: relative; */ - --left-mobile-val: calc( + + /* --left-mobile-val: calc( 0px - var(--layout-mobile-padding) - var(--highlighted-text-gap-left, clamp(-30px, -1.4vw, -2px)) - ); + ); */ --left-pos: calc(0px - var(--highlighted-text-gap-left)); - padding-right: clamp(2px, 1.4vw, 30px); + padding-right: clamp(2px, 1.4vw, 30px); left: var(--left-pos); } } @@ -74,14 +61,16 @@ span.-highlighted, --highlighted-bg-color-1: var(--theme-current-color); --highlighted-bg-color-2: var(--theme-current-color); - --highlighted-bg: linear-gradient(var(--highlighted-bg-color-1), var(--highlighted-bg-color-2)); color: var(--color-bg); + /* TODO: Gotham balance padding */ - padding: 4.55px 2px 0 2px; + padding: 4.55px 2px 0; background-image: var(--highlighted-bg); + /* -webkit-box-decoration-break: clone; */ + /* box-decoration-break: clone; */ } @@ -94,14 +83,15 @@ span.-highlighted, padding-left: clamp(2px, 1.4vw, 30px); } */ -@media (min-width: 80rem) { +@media (width >= 48rem) { /* 1280px */ .-highlighted.-animate > span { color: var(--theme-current-color); - --animate-in: highlight-to-left 0.5s 0.1s forwards; - --animate-out: highlight-to-right 0.4s forwards; + + /* --animate-in: highlight-to-left 0.5s 0.1s forwards; */ + + /* --animate-out: var(--is-hovered-once, highlight-to-right 0.4s forwards); */ background-size: 0% 100%; - -webkit-background-clip: padding-box, text; background-clip: padding-box, text; background-repeat: no-repeat; background-position: left; @@ -113,12 +103,15 @@ span.-highlighted, --animate-out: highlight-to-left 0.4s 0.1s forwards; } - .-highlighted.-animate:hover > span { - --highlight-animate: var(--animate-in); + .-highlighted.-animate:not(:hover) > span { + background-size: 100% 100%; + color: var(--color-bg); + + --highlight-animate: var(--is-not-hovered-yet, var(--animate-out)); } - .-highlighted.-animate:not(:hover) > span { - --highlight-animate: var(--animate-out); + .-highlighted.-animate:hover > span { + --highlight-animate: var(--animate-in); } } @@ -126,9 +119,11 @@ span.-highlighted, 0% { background-size: 0% 100%; } + 50% { background-size: 100% 100%; } + 100% { background-size: 100% 100%; background-image: var(--highlighted-bg); @@ -142,10 +137,12 @@ span.-highlighted, background-image: var(--highlighted-bg); color: var(--color-bg); } + 50% { background-size: 100% 100%; background-position: right; } + 100% { background-size: 0% 100%; background-color: transparent; diff --git a/src/components/YHighlightedText/YHighlightedText.stories.ts b/src/components/YHighlightedText/YHighlightedText.stories.ts index a52fd05a..83e85a6a 100644 --- a/src/components/YHighlightedText/YHighlightedText.stories.ts +++ b/src/components/YHighlightedText/YHighlightedText.stories.ts @@ -19,9 +19,14 @@ const renderGenericStory: Story = { props: Object.keys(argTypes), template: `
- - Highlighted Text Highlighted Text Highlighted
Text Highlighted Text Highlighted Text + + Title active not animated +

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam nec purus nec + ligula luctus aliquam. Nulla facilisi. Nulla facilisi. Nulla facilisi. Nulla + facilisi. Nulla facilisi. Nulla facilisi. Nulla facilisi. Nulla facilisi. +

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam nec purus nec ligula luctus aliquam. Nulla facilisi. Nulla facilisi. Nulla facilisi. Nulla diff --git a/src/components/YHighlightedText/YHighlightedText.vue b/src/components/YHighlightedText/YHighlightedText.vue index afe7a7f9..5afc8924 100644 --- a/src/components/YHighlightedText/YHighlightedText.vue +++ b/src/components/YHighlightedText/YHighlightedText.vue @@ -10,13 +10,14 @@ diff --git a/src/components/YHighlightedText/types.ts b/src/components/YHighlightedText/types.ts index 7e4acf12..b466397c 100644 --- a/src/components/YHighlightedText/types.ts +++ b/src/components/YHighlightedText/types.ts @@ -1,4 +1,6 @@ -export interface YHighlightedTextProps { +import { ColorProps } from '@/composables/theming/color' + +export interface YHighlightedTextProps extends ColorProps { as?: 'p' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'span' | 'div' animate?: boolean active?: boolean diff --git a/src/components/YInput/YInput.vue b/src/components/YInput/YInput.vue index 27c61dd0..e469d54f 100644 --- a/src/components/YInput/YInput.vue +++ b/src/components/YInput/YInput.vue @@ -2,15 +2,19 @@ {{ label }} @@ -21,7 +25,7 @@ import { useAttrs, useTemplateRef } from 'vue' import { YLabel } from '@/components/YLabel' import { useColor, useRaw, useSize, useState, useVariant } from '@/composables' import { useComponentProps } from '@/composables/component' -import { inputEventsKey, inputEventsKeyInterface } from '@/composables/input' +import { inputEventsKey } from '@/composables/input' import { computed, inject } from 'vue' import './YInput.css' import { YInputProps } from './types' @@ -78,7 +82,17 @@ const { sizeClass } = useSize(props) const { rawClasses } = useRaw(props) const attrs = useAttrs() -const { handleEvent, modelValue } = inject(inputEventsKey) as inputEventsKeyInterface +// const { handleEvent, modelValue } = inject(inputEventsKey) as inputEventsKeyInterface + +const injected = inject(inputEventsKey, null) + +const handleEvent = + injected?.handleEvent ?? + ((e: Event) => { + if (isDisabled.value) e.preventDefault() + }) + +const modelValue = injected?.modelValue ?? computed(() => props.modelValue ?? '') // Apply classes and styles to the input element const componentProps = useComponentProps({ diff --git a/src/components/YInputText/YInputText.vue b/src/components/YInputText/YInputText.vue index 5092b31c..645252c5 100644 --- a/src/components/YInputText/YInputText.vue +++ b/src/components/YInputText/YInputText.vue @@ -4,8 +4,8 @@ v-bind="props" input-class="y-input-text" type="text" - :value="modelValue" - @input="handleInput" + :model-value="modelValue" + @change="updateModelValue" /> @@ -22,5 +22,5 @@ const props = withDefaults(defineProps(), { const emit: EmitFn = defineEmits(['update:modelValue', 'input', 'change', 'blur']) const attrs = useAttrs() -const { modelValue, handleInput } = useInput({ props, attrs, emit }) +const { modelValue, updateModelValue } = useInput({ props, attrs, emit }) diff --git a/src/components/YMenu/YMenu.css b/src/components/YMenu/YMenu.css index a89deddf..79f00a37 100644 --- a/src/components/YMenu/YMenu.css +++ b/src/components/YMenu/YMenu.css @@ -8,5 +8,6 @@ background-color: inherit; padding-left: 1rem; padding-right: 1rem; + --component-box-shadow: var(--component-box-shadow); } diff --git a/src/components/YMenu/YMenu.scss b/src/components/YMenu/YMenu.scss index 7d166d43..685a713a 100644 --- a/src/components/YMenu/YMenu.scss +++ b/src/components/YMenu/YMenu.scss @@ -3,6 +3,7 @@ @use '@/assets/scss/global.scss' as *; @use '@/assets/scss/theme/state' as state; @use '@/assets/scss/theme/color' as color; + // TODO: change to kebab-case .y-menu { // @include theme-component; @@ -18,5 +19,6 @@ background-color: inherit; /* rt-bg-white */ padding-left: 1rem; /* rt-px-4 -> 16px */ padding-right: 1rem; /* rt-px-4 -> 16px */ + @include utils.component(box-shadow, utils.component(box-shadow)); } diff --git a/src/components/YModal/YModal.css b/src/components/YModal/YModal.css index 1857b9c1..99558843 100644 --- a/src/components/YModal/YModal.css +++ b/src/components/YModal/YModal.css @@ -75,7 +75,7 @@ } } -@media (min-width: 768px) { +@media (width >= 768px) { .y-modal { width: var(--modal-size, var(--modal-size-default)); } @@ -115,5 +115,6 @@ .y-modal-footer .y-button { --component-margin-bottom: var(--component-box-shadow-y); + border: var(--component-border); } diff --git a/src/components/YRow/YRow.stories.ts b/src/components/YRow/YRow.stories.ts new file mode 100644 index 00000000..b08ede05 --- /dev/null +++ b/src/components/YRow/YRow.stories.ts @@ -0,0 +1,50 @@ +import type { Meta, StoryObj } from '@storybook/vue3-vite' +import { boxArgTypes } from '../YBox/YBox.stories' +import YRow from './YRow.vue' +// import { useThemeComponentStory } from '@/composables' + +// const { commonArgTypes, commonArgs, generateCommonStories } = useThemeComponentStory(YRow) + +const meta: Meta = { + // TODO: TO CHANGE PATH + title: 'Components/YRow', + component: YRow, + tags: ['autodocs'], + argTypes: { + type: { control: 'select', options: ['default', 'cluster', 'switcher'] }, + ...boxArgTypes, + }, + args: { + type: 'default', + // ...commonArgs, + }, +} + +export default meta +type Story = StoryObj + +const renderGenericStory: Story = { + render: (args, { argTypes }) => ({ + components: { YRow }, + props: Object.keys(argTypes), + template: ` + +

Column 1
+
Column 2
+
Column 3
+
Column 4
+
Column 5
+ + `, + setup() { + return { args } + }, + }), +} + +export { renderGenericStory as Default } + +// TODO: if you use useThemeComponentStory +// const { Default, Outlined, Disabled, Raw, Small, Large } = generateCommonStories(renderGenericStory) + +// export { Default, Outlined, Disabled, Raw, Small, Large } diff --git a/src/components/YRow/YRow.test.ts b/src/components/YRow/YRow.test.ts new file mode 100644 index 00000000..1003ad2a --- /dev/null +++ b/src/components/YRow/YRow.test.ts @@ -0,0 +1,17 @@ +import { render } from '@testing-library/vue' +import { describe, expect, it } from 'vitest' + +import YRow from './YRow.vue' + +describe('YRow', () => { + it('renders', () => { + const yrow = render(YRow, { + // slots: { + // default: 'Default content for YRow component', + // }, + }) + + // expect(yrow.html()).toContain('Default content for YRow component') + expect(yrow.html()).toMatchSnapshot() + }) +}) diff --git a/src/components/YRow/YRow.vue b/src/components/YRow/YRow.vue new file mode 100644 index 00000000..5de47ffb --- /dev/null +++ b/src/components/YRow/YRow.vue @@ -0,0 +1,32 @@ + + + diff --git a/src/components/YRow/__snapshots__/YRow.test.ts.snap b/src/components/YRow/__snapshots__/YRow.test.ts.snap new file mode 100644 index 00000000..bc705c79 --- /dev/null +++ b/src/components/YRow/__snapshots__/YRow.test.ts.snap @@ -0,0 +1,7 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`YRow > renders 1`] = ` +"
+

Default content for YRow component

+
" +`; diff --git a/src/components/YRow/index.ts b/src/components/YRow/index.ts new file mode 100644 index 00000000..6dfae687 --- /dev/null +++ b/src/components/YRow/index.ts @@ -0,0 +1 @@ +export { default as YRow } from './YRow.vue' \ No newline at end of file diff --git a/src/components/YSection/YSection.css b/src/components/YSection/YSection.css index 604b49ca..4051015a 100644 --- a/src/components/YSection/YSection.css +++ b/src/components/YSection/YSection.css @@ -1,18 +1,21 @@ .y-section { - width: 100%; - display: flex; - flex-wrap: wrap; - padding: 15px 22px 10px; + /* width: 100%; */ + --padding-xs: var(--media-xs) 15px 22px 10px; + --padding-sm: var(--media-sm) 40px 20px 10px 0; + --padding-md: var(--media-md) 50px 37px 0 0; + + padding: var(--padding-md, var(--padding-sm, var(--padding-xs))); &:last-child { padding-bottom: 22px; } } -@media (min-width: 768px) { +@media (width >= 768px) { .y-section { flex-wrap: nowrap; - padding: 40px 20px 10px 0; + + /* padding: 40px 20px 10px 0; */ .y-vertical-title { --space-unit: 1rem; @@ -21,12 +24,12 @@ } } -@media (min-width: 1024px) { +@media (width >= 1024px) { .y-section { - padding: 50px 37px 0 0; + /* padding: 50px 37px 0 0; */ &:last-child { - padding-bottom: 50px; + /* padding-bottom: 50px; */ } } } diff --git a/src/components/YSection/YSection.vue b/src/components/YSection/YSection.vue index 348f9a63..6d7a6356 100644 --- a/src/components/YSection/YSection.vue +++ b/src/components/YSection/YSection.vue @@ -1,17 +1,17 @@ diff --git a/src/components/YStack/__snapshots__/YStack.test.ts.snap b/src/components/YStack/__snapshots__/YStack.test.ts.snap new file mode 100644 index 00000000..0214230b --- /dev/null +++ b/src/components/YStack/__snapshots__/YStack.test.ts.snap @@ -0,0 +1,7 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`YStack > renders 1`] = ` +"
+

Default content for YStack component

+
" +`; diff --git a/src/components/YStack/index.ts b/src/components/YStack/index.ts new file mode 100644 index 00000000..b9d5ac72 --- /dev/null +++ b/src/components/YStack/index.ts @@ -0,0 +1 @@ +export { default as YStack } from './YStack.vue' \ No newline at end of file diff --git a/src/components/YTable/YTable.scss b/src/components/YTable/YTable.scss index e19993a5..3888f599 100644 --- a/src/components/YTable/YTable.scss +++ b/src/components/YTable/YTable.scss @@ -20,8 +20,8 @@ &:hover { .y-table-data-cell { opacity: 0.6; - background-color: var(--color-primary-20); + &:hover { opacity: 1; background-color: var(--color-primary-30); @@ -35,6 +35,7 @@ background-color: var(--color-background); } } + .y-table-row { // border-bottom: utils.space(xxs) solid utils.color(primary); diff --git a/src/components/YTag/YTag.css b/src/components/YTag/YTag.css index 16ed3b92..42f1bfdd 100644 --- a/src/components/YTag/YTag.css +++ b/src/components/YTag/YTag.css @@ -1,5 +1,6 @@ .y-tag { display: inline-flex; + --component-margin-bottom: none; --component-padding-y: 0.15rem; diff --git a/src/components/YTag/YTag.scss b/src/components/YTag/YTag.scss index 8691c556..f7e007dd 100644 --- a/src/components/YTag/YTag.scss +++ b/src/components/YTag/YTag.scss @@ -7,7 +7,9 @@ @include theme-component; display: inline-flex; + @include utils.component(margin-bottom, none); + // text-transform: uppercase; @include utils.component(padding-y, 0.15rem); diff --git a/src/components/YThemePicker/YThemePicker.vue b/src/components/YThemePicker/YThemePicker.vue index 345b0aa9..33ff3ac2 100644 --- a/src/components/YThemePicker/YThemePicker.vue +++ b/src/components/YThemePicker/YThemePicker.vue @@ -1,24 +1,36 @@ diff --git a/src/components/YVerticalTitle/YVerticalTitle.css b/src/components/YVerticalTitle/YVerticalTitle.css index 29a76ad0..ce217d48 100644 --- a/src/components/YVerticalTitle/YVerticalTitle.css +++ b/src/components/YVerticalTitle/YVerticalTitle.css @@ -13,13 +13,12 @@ color: var(--theme-color); position: relative; z-index: 1; - min-height: var(--heading-height); text-align: center; flex: 1 0 100%; } -@media (min-width: 768px) { +@media (width >= 768px) { .y-vertical-title { font-size: var(--y-vertical-title-font-size-md); display: flex; @@ -34,13 +33,13 @@ } } -@media (min-width: 1024px) { +@media (width >= 1024px) { .y-vertical-title { padding: 0 46px 0 37px; } } -@media (min-width: 1280px) { +@media (width >= 1280px) { .y-vertical-title { font-size: var(--y-vertical-title-font-size-xs-and-xl); } diff --git a/src/components/YVerticalTitle/YVerticalTitle.scss b/src/components/YVerticalTitle/YVerticalTitle.scss index 584b606b..914877d8 100644 --- a/src/components/YVerticalTitle/YVerticalTitle.scss +++ b/src/components/YVerticalTitle/YVerticalTitle.scss @@ -19,7 +19,6 @@ color: var(--theme-color); position: relative; z-index: 1; - min-height: var(--heading-height); text-align: center; flex: 1 0 100%; diff --git a/src/components/utils.ts b/src/components/utils.ts new file mode 100644 index 00000000..3ca1cc48 --- /dev/null +++ b/src/components/utils.ts @@ -0,0 +1,260 @@ +import { PropType } from 'vue' +import type { DesignTokens } from '../assets/css/themes/tokens/types/theme' + +// TODO: Review as done by Claude 80% +export { + getSpacingOptions, + isDefined, + parseBackgroundColorProps, + parseBorderProps, + parseHeightProps, + parseMarginProps, + parsePaddingProps, + parseRadiusProps, + parseWidthProps, +} + +function isDefined(value: unknown): boolean { + return value !== undefined && value !== null +} + +// Derive types from DesignTokens interface (type-only import, no runtime dependency) +export type SpacingKey = keyof DesignTokens['spacing'] +export type RadiusKey = keyof DesignTokens['radius'] +export type WidthKey = keyof DesignTokens['cube']['utility']['width'] +export type HeightKey = keyof DesignTokens['cube']['utility']['height'] +export type MarginKey = SpacingKey | 'auto' | '0' +export type BorderKey = + | keyof DesignTokens['cube']['utility']['border'] + | keyof DesignTokens['cube']['utility']['border']['theme'] + | keyof DesignTokens['cube']['utility']['border']['width'] +export type BackgroundColorKey = keyof DesignTokens['cube']['utility']['bg'] + +const spacingOptions: SpacingKey[] = ['xxs', 'xs', 'sm', 'md', 'lg', 'xl', 'xxl'] + +function getSpacingOptions(): SpacingKey[] { + return spacingOptions +} + +/** + * Take a input to represent padding in a Vue component props and generate corresponding utility classes + * + * e.g. + * padding="md sm xs lg" => will generate ['padding-top-md', 'padding-right-sm', 'padding-bottom-xs', 'padding-left-lg'] + * + * @param {(SpacingKey | SpacingKey[])} paddingProps + * @returns {(string | string[])} + */ +function parsePaddingProps(paddingProps?: SpacingKey | SpacingKey[]): string | string[] { + if (!isDefined(paddingProps)) { + return [] + } + + const values = paddingProps + ?.toString() + .split(' ') + .map((v) => v.trim()) + + if (values && values.length === 1) { + const value = values[0] + + return [`padding-${value}`] + } + + if (values && values.length === 2) { + const [vertical, horizontal] = values + return [`padding-x-${horizontal}`, `padding-y-${vertical}`] + } + + if (values && values.length === 3) { + const [top, horizontal, bottom] = values + return [`padding-top-${top}`, `padding-x-${horizontal}`, `padding-bottom-${bottom}`] + } + + if (values && values.length === 4) { + const [top, right, bottom, left] = values + return [ + `padding-top-${top}`, + `padding-right-${right}`, + `padding-bottom-${bottom}`, + `padding-left-${left}`, + ] + } + + return [] +} + +export function definePropsFromType() { + return {} as { + [K in keyof T]: { + type: PropType + } + } +} + +function parseRadiusProps(radiusProps?: RadiusKey | RadiusKey[]): string | string[] { + if (!isDefined(radiusProps)) { + return [] + } + + const values = radiusProps + ?.toString() + .split(' ') + .map((v) => v.trim()) + + if (values && values.length === 1) { + const value = values[0] + + return [`radius-${value}`] + } + + if (values && values.length === 2) { + const [top, bottom] = values + return [`radius-y-top-${top}`, `radius-y-bottom-${bottom}`] + } + + if (values && values.length === 3) { + const [topLeft, topRight, bottom] = values + return [`radius-top-left-${topLeft}`, `radius-top-right-${topRight}`, `radius-bottom-${bottom}`] + } + + if (values && values.length === 4) { + const [topLeft, topRight, bottomRight, bottomLeft] = values + return [ + `radius-top-left-${topLeft}`, + `radius-top-right-${topRight}`, + `radius-bottom-right-${bottomRight}`, + `radius-bottom-left-${bottomLeft}`, + ] + } + + return [] +} + +/** + * Parse width prop and generate corresponding utility class + * + * e.g. + * width="full" => ['width-full'] + * + * @param {WidthKey} widthProps + * @returns {string[]} + */ +function parseWidthProps(widthProps?: WidthKey): string[] { + if (!isDefined(widthProps)) { + return [] + } + return [`width-${widthProps}`] +} + +/** + * Parse height prop and generate corresponding utility class + * + * e.g. + * height="screen" => ['height-screen'] + * + * @param {HeightKey} heightProps + * @returns {string[]} + */ +function parseHeightProps(heightProps?: HeightKey): string[] { + if (!isDefined(heightProps)) { + return [] + } + return [`height-${heightProps}`] +} + +/** + * Parse margin prop and generate corresponding utility classes + * Follows the same CSS shorthand pattern as padding + * + * e.g. + * margin="md" => ['margin-md'] + * margin="md lg" => ['margin-y-md', 'margin-x-lg'] + * margin="md lg sm" => ['margin-top-md', 'margin-x-lg', 'margin-bottom-sm'] + * margin="md lg sm xl" => ['margin-top-md', 'margin-right-lg', 'margin-bottom-sm', 'margin-left-xl'] + * + * @param {(MarginKey | MarginKey[])} marginProps + * @returns {string[]} + */ +function parseMarginProps(marginProps?: MarginKey | MarginKey[]): string[] { + if (!isDefined(marginProps)) { + return [] + } + + const values = marginProps + ?.toString() + .split(' ') + .map((v) => v.trim()) + + if (values && values.length === 1) { + const value = values[0] + return [`margin-${value}`] + } + + if (values && values.length === 2) { + const [vertical, horizontal] = values + return [`margin-y-${vertical}`, `margin-x-${horizontal}`] + } + + if (values && values.length === 3) { + const [top, horizontal, bottom] = values + return [`margin-top-${top}`, `margin-x-${horizontal}`, `margin-bottom-${bottom}`] + } + + if (values && values.length === 4) { + const [top, right, bottom, left] = values + return [ + `margin-top-${top}`, + `margin-right-${right}`, + `margin-bottom-${bottom}`, + `margin-left-${left}`, + ] + } + + return [] +} + +/** + * Parse border prop and generate corresponding utility classes + * + * e.g. + * border="all" => ['border-all'] + * border="top bottom" => ['border-top', 'border-bottom'] + * + * @param {(BorderKey | BorderKey[])} borderProps + * @returns {string[]} + */ +function parseBorderProps(borderProps?: BorderKey | BorderKey[]): string[] { + if (!isDefined(borderProps)) { + return [] + } + + if (Array.isArray(borderProps)) { + return borderProps.map((v) => `border-${v}`) + } + const values = borderProps + ?.toString() + .split(' ') + .map((v) => v.trim()) + if (!values || values.length === 0) { + return [] + } + + return values.map((v) => `border-${v}`) +} + +/** + * Parse backgroundColor prop and generate corresponding utility class + * + * e.g. + * backgroundColor="primary" => ['bg-primary'] + * + * @param {BackgroundColorKey} backgroundColorProps + * @returns {string[]} + */ +function parseBackgroundColorProps(backgroundColorProps?: BackgroundColorKey): string[] { + if (!isDefined(backgroundColorProps)) { + return [] + } + return [`bg-${backgroundColorProps}`] +} diff --git a/src/composables/animation.ts b/src/composables/animation.ts index 928f6bf1..8a5a8a48 100644 --- a/src/composables/animation.ts +++ b/src/composables/animation.ts @@ -64,7 +64,7 @@ export function useHoverEvent(target: MaybeRefOrGetter) { console.warn('📟 - element is undefined or null', element) return } - element.style.setProperty('--is-not-hovered-yet', 'none') + element.style.setProperty('--is-not-hovered-yet', ' ;') }) watch( @@ -76,7 +76,7 @@ export function useHoverEvent(target: MaybeRefOrGetter) { return } if (newVal && element instanceof HTMLElement) { - element.style.removeProperty('--has-changed-once') + element.style.setProperty('--is-not-hovered-yet', 'initial') } }, ) diff --git a/src/composables/event.ts b/src/composables/event.ts index 45ca1d23..2731ab9d 100644 --- a/src/composables/event.ts +++ b/src/composables/event.ts @@ -71,7 +71,7 @@ export function useInputEvent(props: YInputProps, attrs: Record emit('change', value) break case 'focus': - el.focus() + emit('focus', value) break case 'blur': emit('blur', value) diff --git a/src/composables/use-theme-tokens.ts b/src/composables/use-theme-tokens.ts index 3e0b0599..3ac24e96 100644 --- a/src/composables/use-theme-tokens.ts +++ b/src/composables/use-theme-tokens.ts @@ -1,16 +1,19 @@ -import { YThemeToken } from '@/assets/css/tokens/types/theme' +// use-theme-tokens.ts import { isClientSide } from '@/utils/is-client-side' +import type { YThemeToken } from 'unholy-tokens/types/tokens' -// TODO: rewrite (GPT) -export type YThemeTokenName = keyof YThemeToken // e.g. "border-radius-base" | ... -export type YCssVarName = `--${YThemeTokenName}` // e.g. "--border-radius-base" | ... +// ✅ only string keys +export type YThemeTokenName = Extract + +// ✅ css var union +export type YCssVarName = `--${YThemeTokenName}` export function useThemeTokens(target: HTMLElement = document.documentElement) { - type Token = keyof YThemeToken + type Token = YThemeTokenName const setToken = (token: Token, value: string | null) => { if (!isClientSide()) return - const cssVar = `--${token}` as const + const cssVar = `--${token}` as YCssVarName if (value === null) target.style.removeProperty(cssVar) else target.style.setProperty(cssVar, value) } diff --git a/src/index.ts b/src/index.ts index d3e96da7..b32d72d7 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,10 +1,5 @@ -// import { Wrapper } from './components' - -// export { Wrapper } -// import './assets/scss/main.scss' - -// import { Wrapper, YButton, YInput, Container, Flex, Card, Highlighted } from './components' - +// Supports weights 100-900 +import '@fontsource-variable/roboto' // Composables export * from './components' export * from './composables' diff --git a/stylelint.config.mjs b/stylelint.config.mjs index b8d5af94..68a47925 100644 --- a/stylelint.config.mjs +++ b/stylelint.config.mjs @@ -1,5 +1,10 @@ export default { - ignoreFiles: ['storybook-static/**', 'dist/**', 'node_modules/**'], + ignoreFiles: [ + 'storybook-static/**', + 'dist/**', + 'node_modules/**', + 'src/assets/css/themes/tokens/**', + ], extends: [ 'stylelint-config-standard', 'stylelint-config-standard-scss', diff --git a/tsconfig.json b/tsconfig.json index d463c786..e3399953 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -23,7 +23,12 @@ "baseUrl": ".", "paths": { - "@/*": ["src/*"] + "@/*": ["src/*"], + "@/components/*": ["src/components/*"], + "@/composables/*": ["src/composables/*"], + "@/utils/*": ["src/utils/*"], + "@/assets/*": ["src/assets/*"], + "unholy-tokens/*": ["src/assets/css/themes/tokens/*"] } }, "include": [ diff --git a/vite.config.ts b/vite.config.ts index 0324eaa2..876624de 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -5,6 +5,7 @@ import { fileURLToPath, URL } from 'url' import { defineConfig } from 'vite' import dts from 'vite-plugin-dts' import vueDevTools from 'vite-plugin-vue-devtools' +import tsconfigPaths from 'vite-tsconfig-paths' // const pathSrc = resolve(__dirname, './src') @@ -16,6 +17,8 @@ export default defineConfig(({ mode }) => { return { plugins: [ vue(), + // Give vite the ability to resolve imports using TypeScript's path mapping. + tsconfigPaths(), dts({ entryRoot: './src', tsconfigPath: fileURLToPath(new URL('./tsconfig.json', import.meta.url)), @@ -33,6 +36,7 @@ export default defineConfig(({ mode }) => { alias: [ { find: '@', replacement: fileURLToPath(new URL('./src/', import.meta.url)) }, { find: '../../../', replacement: fileURLToPath(new URL('./src/assets', import.meta.url)) }, + { find: 'unholy-tokens/*', replacement: 'src/assets/css/themes/tokens/*' }, ], }, // publicDir: 'public',