From 036aa3d9be58295ebca232aa2d02ada54679b3c1 Mon Sep 17 00:00:00 2001 From: Ron Lucke Date: Tue, 10 Mar 2026 08:50:42 +0100 Subject: add basics for essential components --- .../src/components/SuiButton/SuiButton.vue | 39 +++++ .../SuiButtonGroup/SuiButtonGroup.stories.js | 45 ++++++ .../components/SuiButtonGroup/SuiButtonGroup.vue | 26 ++++ packages/studip-ui/src/components/index.js | 4 + packages/studip-ui/src/composables/index.js | 2 +- .../studip-ui/src/composables/useSlotFilter.js | 25 +++ packages/studip-ui/src/styles/components/_btn.scss | 27 ++++ .../studip-ui/src/styles/components/index.scss | 1 + packages/studip-ui/src/styles/main.scss | 5 +- packages/studip-ui/src/styles/tokens/_base.scss | 7 + packages/studip-ui/src/styles/tokens/_colors.scss | 140 ----------------- .../studip-ui/src/styles/tokens/_elevation.scss | 1 + packages/studip-ui/src/styles/tokens/_opacity.scss | 9 ++ packages/studip-ui/src/styles/tokens/_radius.scss | 14 ++ packages/studip-ui/src/styles/tokens/_sizes.scss | 25 +++ packages/studip-ui/src/styles/tokens/_spacing.scss | 15 ++ .../studip-ui/src/styles/tokens/_transition.scss | 1 + .../src/styles/tokens/colors/_action.scss | 17 +++ .../src/styles/tokens/colors/_border.scss | 10 ++ .../studip-ui/src/styles/tokens/colors/_brand.scss | 11 ++ .../studip-ui/src/styles/tokens/colors/_color.scss | 119 +++++++++++++++ .../src/styles/tokens/colors/_content.scss | 10 ++ .../src/styles/tokens/colors/_feedback.scss | 10 ++ .../src/styles/tokens/colors/_graphic.scss | 10 ++ .../src/styles/tokens/colors/_structure.scss | 10 ++ .../src/styles/tokens/colors/_surface.scss | 48 ++++++ .../studip-ui/src/styles/tokens/colors/_text.scss | 10 ++ .../studip-ui/src/styles/tokens/colors/_utils.scss | 10 ++ .../studip-ui/src/styles/tokens/colors/index.scss | 169 +++++++++++++++++++++ .../src/styles/tokens/components/_button.scss | 0 .../src/styles/tokens/components/index.scss | 0 packages/studip-ui/src/styles/tokens/index.scss | 62 +++++++- 32 files changed, 732 insertions(+), 150 deletions(-) create mode 100644 packages/studip-ui/src/components/SuiButton/SuiButton.vue create mode 100644 packages/studip-ui/src/components/SuiButtonGroup/SuiButtonGroup.stories.js create mode 100644 packages/studip-ui/src/components/SuiButtonGroup/SuiButtonGroup.vue create mode 100644 packages/studip-ui/src/composables/useSlotFilter.js create mode 100644 packages/studip-ui/src/styles/components/_btn.scss create mode 100644 packages/studip-ui/src/styles/components/index.scss create mode 100644 packages/studip-ui/src/styles/tokens/_base.scss delete mode 100644 packages/studip-ui/src/styles/tokens/_colors.scss create mode 100644 packages/studip-ui/src/styles/tokens/_elevation.scss create mode 100644 packages/studip-ui/src/styles/tokens/_opacity.scss create mode 100644 packages/studip-ui/src/styles/tokens/_radius.scss create mode 100644 packages/studip-ui/src/styles/tokens/_sizes.scss create mode 100644 packages/studip-ui/src/styles/tokens/_transition.scss create mode 100644 packages/studip-ui/src/styles/tokens/colors/_action.scss create mode 100644 packages/studip-ui/src/styles/tokens/colors/_border.scss create mode 100644 packages/studip-ui/src/styles/tokens/colors/_brand.scss create mode 100644 packages/studip-ui/src/styles/tokens/colors/_color.scss create mode 100644 packages/studip-ui/src/styles/tokens/colors/_content.scss create mode 100644 packages/studip-ui/src/styles/tokens/colors/_feedback.scss create mode 100644 packages/studip-ui/src/styles/tokens/colors/_graphic.scss create mode 100644 packages/studip-ui/src/styles/tokens/colors/_structure.scss create mode 100644 packages/studip-ui/src/styles/tokens/colors/_surface.scss create mode 100644 packages/studip-ui/src/styles/tokens/colors/_text.scss create mode 100644 packages/studip-ui/src/styles/tokens/colors/_utils.scss create mode 100644 packages/studip-ui/src/styles/tokens/colors/index.scss create mode 100644 packages/studip-ui/src/styles/tokens/components/_button.scss create mode 100644 packages/studip-ui/src/styles/tokens/components/index.scss diff --git a/packages/studip-ui/src/components/SuiButton/SuiButton.vue b/packages/studip-ui/src/components/SuiButton/SuiButton.vue new file mode 100644 index 0000000..27d9c53 --- /dev/null +++ b/packages/studip-ui/src/components/SuiButton/SuiButton.vue @@ -0,0 +1,39 @@ + + \ No newline at end of file diff --git a/packages/studip-ui/src/components/SuiButtonGroup/SuiButtonGroup.stories.js b/packages/studip-ui/src/components/SuiButtonGroup/SuiButtonGroup.stories.js new file mode 100644 index 0000000..56c1dbb --- /dev/null +++ b/packages/studip-ui/src/components/SuiButtonGroup/SuiButtonGroup.stories.js @@ -0,0 +1,45 @@ +// SuiButtonGroup.stories.js +import SuiButtonGroup from './SuiButtonGroup.vue'; +import SuiButton from './../SuiButton/SuiButton.vue'; + +const meta = { + title: 'Stud.IP UI Elements/ButtonGroup', + component: SuiButtonGroup, + tags: ['autodocs', 'since:6.3.0', 'new', 'alpha'], + subcomponents: { SuiButton }, + parameters: { + docs: { + description: { + component: '' + }, + }, + }, + argTypes: {} +}; + + + +export default meta; + + +export const SlotValidationTest = { + args: { + }, + render: (args) => ({ + components: { SuiButtonGroup, SuiButton }, + setup() { + return { args }; + }, + template: ` + + +
+ Ich bin ein verbotenes DIV und sollte verschwinden! +
+ + Ich bin ein verbotener Text und werde gefiltert. + +
+ `, + }), +}; \ No newline at end of file diff --git a/packages/studip-ui/src/components/SuiButtonGroup/SuiButtonGroup.vue b/packages/studip-ui/src/components/SuiButtonGroup/SuiButtonGroup.vue new file mode 100644 index 0000000..add111a --- /dev/null +++ b/packages/studip-ui/src/components/SuiButtonGroup/SuiButtonGroup.vue @@ -0,0 +1,26 @@ + + + + + \ No newline at end of file diff --git a/packages/studip-ui/src/components/index.js b/packages/studip-ui/src/components/index.js index 2fdf184..992fdab 100644 --- a/packages/studip-ui/src/components/index.js +++ b/packages/studip-ui/src/components/index.js @@ -1,8 +1,12 @@ +import SuiButton from './SuiButton/SuiButton.vue'; +import SuiButtonGroup from './SuiButtonGroup/SuiButtonGroup.vue'; import SuiChip from './SuiChip/SuiChip.vue'; import SuiFormattedTime from './SuiFormattedTime/SuiFormattedTime.vue'; import SuiIcon from './SuiIcon/SuiIcon.vue'; export { + SuiButton, + SuiButtonGroup, SuiChip, SuiFormattedTime, SuiIcon, diff --git a/packages/studip-ui/src/composables/index.js b/packages/studip-ui/src/composables/index.js index cb0ff5c..7ad2d99 100644 --- a/packages/studip-ui/src/composables/index.js +++ b/packages/studip-ui/src/composables/index.js @@ -1 +1 @@ -export {}; +export { useSlotFilter } from './useSlotFilter.js'; \ No newline at end of file diff --git a/packages/studip-ui/src/composables/useSlotFilter.js b/packages/studip-ui/src/composables/useSlotFilter.js new file mode 100644 index 0000000..5b512d9 --- /dev/null +++ b/packages/studip-ui/src/composables/useSlotFilter.js @@ -0,0 +1,25 @@ +// useSlotFilter.js +import { isVNode, Comment } from 'vue'; + +export function useSlotFilter(slots) { + const getValidChildren = (componentName) => { + const rawNodes = slots.default ? slots.default() : []; + + return rawNodes.filter(vnode => { + if (!isVNode(vnode) || vnode.type === Comment) return false; + + const isCorrectComponent = vnode.type?.name === componentName || + vnode.type?.__name === componentName; + + if (!isCorrectComponent) { + if (vnode.type !== Symbol.for('v-fgt')) { + console.warn(`[UI Kit] ButtonGroup: Element vom Typ "${vnode.type?.name || vnode.type}" wurde entfernt.`); + } + return false; + } + return true; + }); + }; + + return { getValidChildren }; +} \ No newline at end of file diff --git a/packages/studip-ui/src/styles/components/_btn.scss b/packages/studip-ui/src/styles/components/_btn.scss new file mode 100644 index 0000000..d16ce18 --- /dev/null +++ b/packages/studip-ui/src/styles/components/_btn.scss @@ -0,0 +1,27 @@ +.sui-btn { + appearance: none; + background: var(--color--global-background); + border: 1px solid var(--color--highlight); + border-radius: 4px; + color: var(--color--highlight); + cursor: pointer; + font-family: inherit; + font-size: 14px; + line-height: 1.3; + padding: 7px 14px; + text-align: center; + white-space: nowrap; + transition: background-color 0.2s, color 0.2s; + margin: 0; + + &:hover:not(:disabled) { + background-color: var(--color--highlight); + color: var(--color--highlight-contrast); + } + + &:disabled { + cursor: not-allowed; + opacity: 0.6; + background: var(--color--button-inactive-background); + } +} \ No newline at end of file diff --git a/packages/studip-ui/src/styles/components/index.scss b/packages/studip-ui/src/styles/components/index.scss new file mode 100644 index 0000000..f5656bf --- /dev/null +++ b/packages/studip-ui/src/styles/components/index.scss @@ -0,0 +1 @@ +@use 'btn' as btn; \ No newline at end of file diff --git a/packages/studip-ui/src/styles/main.scss b/packages/studip-ui/src/styles/main.scss index 0b41bc6..b7ca1e9 100644 --- a/packages/studip-ui/src/styles/main.scss +++ b/packages/studip-ui/src/styles/main.scss @@ -1,2 +1,3 @@ -@use 'tokens/index.scss'; -@use 'reset'; \ No newline at end of file +@use 'tokens/index.scss' as tokens; +@use 'reset'; +@use 'utilities/index.scss' as utilities; \ No newline at end of file diff --git a/packages/studip-ui/src/styles/tokens/_base.scss b/packages/studip-ui/src/styles/tokens/_base.scss new file mode 100644 index 0000000..20ab118 --- /dev/null +++ b/packages/studip-ui/src/styles/tokens/_base.scss @@ -0,0 +1,7 @@ +$base: ( + content: (), + sidebar: (), + mainnav: (), + topbar: (), + footer: () +); \ No newline at end of file diff --git a/packages/studip-ui/src/styles/tokens/_colors.scss b/packages/studip-ui/src/styles/tokens/_colors.scss deleted file mode 100644 index 1136880..0000000 --- a/packages/studip-ui/src/styles/tokens/_colors.scss +++ /dev/null @@ -1,140 +0,0 @@ -// base colors -$color--black: #000; -$color--blue-1: #28497c; -$color--blue-2: #36598f; -$color--blue-3: #d0d7e3; -$color--gray-1: #101010; -$color--gray-2: #3c454e; -$color--gray-3: #676767; -$color--gray-4: #909090; -$color--gray-5: #d8d8d8; -$color--gray-6: #ededed; -$color--gray-7: #fbfbfc; -$color--green-1: #6ead10; -$color--green-2: #e2efcf; -$color--red-1: #d60000; -$color--red-2: #f7cccc; -$color--white: #fff; -$color--yellow-1: #ffbc33; -$color--yellow-2: #fff2d6; - -// color names - -$color--global-background: $color--white; - -$color--font-primary: $color--gray-1; -$color--font-secondary: $color--gray-3; -$color--font-inactive: $color--gray-3; -$color--font-inverted: $color--white; - - -$color--brand-primary: $color--blue-1; -$color--brand-primary-contrast: $color--font-inverted; -$color--brand-secondary: $color--gray-2; -$color--brand-secondary-contrast: $color--font-inverted; - -$color--highlight: $color--blue-1; -$color--highlight-hover: $color--red-1; -$color--highlight-contrast: $color--font-inverted; - -$color--content-link: $color--blue-1; -$color--content-link-hover: $color--red-1; - -$color--sidebar-item: $color--blue-1; -$color--sidebar-item-hover: $color--gray-1; - -$color--main-navigation-background: $color--gray-7; -$color--main-navigation-border: $color--gray-5; -$color--main-navigation-item: $color--blue-1; -$color--main-navigation-item-inactive: $color--gray-4; - -$color--sidebar-marker-active: $color--gray-5; -$color--sidebar-marker-active-navigation: $color--blue-1; -$color--sidebar-marker-active-view: $color--yellow-1; -$color--sidebar-marker-focus: $color--gray-5; -$color--sidebar-marker-hover: $color--gray-5; -$color--sidebar-active: $color--gray-6; -$color--sidebar-focus: $color--gray-6; -$color--sidebar-hover: $color--gray-6; -$color--sidebar-divider: $color--gray-6; - -$color--action-menu-border: $color--gray-5; -$color--action-menu-divider: $color--gray-6; -$color--action-menu-hover: $color--gray-6; -$color--action-menu-marker-hover: $color--gray-5; -$color--action-menu-shadow: $color--gray-5; - -$color--dialog-overlay: $color--gray-1; - -$color--tile-border-focus: $color--gray-4; -$color--tile-border-hover: $color--gray-4; -$color--tile-border: $color--gray-5; -$color--tile-background: $color--gray-7; -$color--tile-background-active: $color--gray-6; -$color--tile-background-focus: $color--gray-6; -$color--tile-background-hover: $color--gray-6; -$color--tile-marker-inactive: $color--gray-4; -$color--tile-marker-active: $color--green-1; -$color--tile-marker-attention: $color--yellow-1; -$color--tile-title-background: $color--gray-6; - -$color--scrollbar-thumb: $color--gray-5; - -$color--content-bar-background: $color--gray-6; - -$color--content-box-border: $color--gray-6; -$color--content-box-header: $color--gray-6; -$color--content-box-background: $color--white; - -$color--fieldset-header: $color--gray-6; -$color--fieldset-border: $color--gray-6; - -$color--tabs-marker-hover: $color--gray-4; -$color--tabs-marker-active: $color--gray-3; - -$color--table-header: $color--gray-6; -$color--table-border: $color--gray-6; -$color--table-focus: $color--gray-6; -$color--table-hover: $color--gray-6; - -$color--button-inactive-background: $color--gray-7; -$color--button-inactive-background-contrast: $color--font-inactive; -$color--button-inactive-border: $color--gray-5; - -$color--radiobuttonset-background: $color--white; -$color--radiobuttonset-background-selected: $color--gray-6; -$color--radiobuttonset-border: $color--gray-6; - -$color--input-field-border: $color--gray-5; -$color--input-field-background: $color--white; - -$color--divider: $color--gray-6; -$color--line: $color--gray-6; - -$color--shadow: $color--gray-4; -$color--focus: $color--gray-4; - -$color--warning: $color--red-1; -$color--warning-secondary: $color--red-2; -$color--warning-contrast: $color--font-inverted; -$color--warning-secondary-contrast: $color--font-primary; - -$color--attention: $color--yellow-1; -$color--attention-secondary: $color--yellow-2; -$color--attention-contrast: $color--font-primary; -$color--attention-secondary-contrast: $color--font-primary; - -$color--good: $color--green-1; -$color--good-secondary: $color--green-2; -$color--good-contrast: $color--font-inverted; -$color--good-secondary-contrast: $color--font-primary; - -$color--info: $color--blue-2; -$color--info-secondary: $color--blue-3; -$color--info-contrast: $color--font-inverted; -$color--info-secondary-contrast: $color--font-primary; - -$color--image-placeholder-background: $color--gray-6; -$color--image-placeholder-icon: $color--gray-4; - -$color-header-inverted: $color--white; \ No newline at end of file diff --git a/packages/studip-ui/src/styles/tokens/_elevation.scss b/packages/studip-ui/src/styles/tokens/_elevation.scss new file mode 100644 index 0000000..2517898 --- /dev/null +++ b/packages/studip-ui/src/styles/tokens/_elevation.scss @@ -0,0 +1 @@ +$ref-elevation: (); \ No newline at end of file diff --git a/packages/studip-ui/src/styles/tokens/_opacity.scss b/packages/studip-ui/src/styles/tokens/_opacity.scss new file mode 100644 index 0000000..63bb7c1 --- /dev/null +++ b/packages/studip-ui/src/styles/tokens/_opacity.scss @@ -0,0 +1,9 @@ +@use 'sass:map'; +@use 'sass:math'; + +$ref-opacity: (); + +@for $i from 0 through 10 { + $step: $i * 10; + $ref-opacity: map.merge($ref-opacity, ("#{$step}": math.div($step, 100))); +} \ No newline at end of file diff --git a/packages/studip-ui/src/styles/tokens/_radius.scss b/packages/studip-ui/src/styles/tokens/_radius.scss new file mode 100644 index 0000000..497a66e --- /dev/null +++ b/packages/studip-ui/src/styles/tokens/_radius.scss @@ -0,0 +1,14 @@ +$sys-radius: ( + 'xs': var(--ref-size-025), + 'sm': var(--ref-size-050), + 'md': var(--ref-size-100), + 'lg': var(--ref-size-200), + 'container': ( + 'inner-sm': var(--sys-spacing-xs), + 'outer-sm': calc(var(--sys-radius-sm) + var(--sys-spacing-sm)), + 'inner-md': var(--sys-spacing-sm), + 'outer-md': calc(var(--sys-radius-md) + var(--sys-spacing-md)), + 'inner-lg': var(--sys-spacing-md), + 'outer-lg': calc(var(--sys-radius-lg) + var(--sys-spacing-lg)), + ), +); \ No newline at end of file diff --git a/packages/studip-ui/src/styles/tokens/_sizes.scss b/packages/studip-ui/src/styles/tokens/_sizes.scss new file mode 100644 index 0000000..40038e3 --- /dev/null +++ b/packages/studip-ui/src/styles/tokens/_sizes.scss @@ -0,0 +1,25 @@ +@use 'sass:math'; +@use 'sass:map'; + +$size-base: 0.5rem; + +@function get-size($value) { + @return math.div($value, 100) * $size-base; +} + +$ref-sizes: ( + 0: 0, + 025: get-size(25), + 050: get-size(50), + 075: get-size(75), + 100: get-size(100), + 150: get-size(150), + 200: get-size(200), + 250: get-size(250), + 300: get-size(300), + 400: get-size(400), + 500: get-size(500), + 600: get-size(600), + 800: get-size(800), + 1000: get-size(1000), +); diff --git a/packages/studip-ui/src/styles/tokens/_spacing.scss b/packages/studip-ui/src/styles/tokens/_spacing.scss index e69de29..db67042 100644 --- a/packages/studip-ui/src/styles/tokens/_spacing.scss +++ b/packages/studip-ui/src/styles/tokens/_spacing.scss @@ -0,0 +1,15 @@ +$sys-spacing: ( +'stack-xs': var(--ref-size-025), +'stack-sm': var(--ref-size-050), +'stack-md': var(--ref-size-100), +'inline-xs': var(--ref-size-025), +'inline-sm': var(--ref-size-050), +'inline-md': var(--ref-size-100), +'inset-square-md': var(--ref-size-100), +'inset-squish-sm-v': var(--ref-size-025), +'inset-squish-sm-h': var(--ref-size-050), +'inset-squish-md-v': var(--ref-size-050), +'inset-squish-md-h': var(--ref-size-100), +'inset-stretch-md-v': var(--ref-size-150), +'inset-stretch-md-h': var(--ref-size-100) +); \ No newline at end of file diff --git a/packages/studip-ui/src/styles/tokens/_transition.scss b/packages/studip-ui/src/styles/tokens/_transition.scss new file mode 100644 index 0000000..00d1efc --- /dev/null +++ b/packages/studip-ui/src/styles/tokens/_transition.scss @@ -0,0 +1 @@ +$ref-transition: (); \ No newline at end of file diff --git a/packages/studip-ui/src/styles/tokens/colors/_action.scss b/packages/studip-ui/src/styles/tokens/colors/_action.scss new file mode 100644 index 0000000..0ce64c7 --- /dev/null +++ b/packages/studip-ui/src/styles/tokens/colors/_action.scss @@ -0,0 +1,17 @@ +$theme-bundle: ( + 'light': ( + 'primary': 'var(--ref-color-blue-600)', + 'subtle': 'var(--ref-color-blue-50)', + ), + 'dark': ( + 'primary': 'var(--ref-color-blue-400)', + 'subtle': 'var(--ref-color-blue-950)', + ), + 'hc': ( + 'primary': 'var(--ref-color-blue-900)', + 'subtle': 'var(--ref-white)', + ), + 'dhc-adj': ( + 'primary': 'var(--ref-color-blue-100)', + ) +); \ No newline at end of file diff --git a/packages/studip-ui/src/styles/tokens/colors/_border.scss b/packages/studip-ui/src/styles/tokens/colors/_border.scss new file mode 100644 index 0000000..fea72b2 --- /dev/null +++ b/packages/studip-ui/src/styles/tokens/colors/_border.scss @@ -0,0 +1,10 @@ +$theme-bundle: ( + 'light': ( + ), + 'dark': ( + ), + 'hc': ( + ), + 'dhc-adj': ( + ) +); \ No newline at end of file diff --git a/packages/studip-ui/src/styles/tokens/colors/_brand.scss b/packages/studip-ui/src/styles/tokens/colors/_brand.scss new file mode 100644 index 0000000..0e58574 --- /dev/null +++ b/packages/studip-ui/src/styles/tokens/colors/_brand.scss @@ -0,0 +1,11 @@ +$theme-bundle: ( + 'light': ( + 'primary': 'var(--ref-color-blue-900)', + ), + 'dark': ( + ), + 'hc': ( + ), + 'dhc-adj': ( + ) +); \ No newline at end of file diff --git a/packages/studip-ui/src/styles/tokens/colors/_color.scss b/packages/studip-ui/src/styles/tokens/colors/_color.scss new file mode 100644 index 0000000..25bdd53 --- /dev/null +++ b/packages/studip-ui/src/styles/tokens/colors/_color.scss @@ -0,0 +1,119 @@ +$ref-color: ( + 'black': #000000, + + 'blue': ( + 0: #cbd3e0, + 50: #c0cad9, + 100: #b5c1d3, + 150: #aab7cc, + 200: #a0aec5, + 250: #95a5bf, + 300: #8a9cb8, + 350: #7f93b1, + 400: #7489ab, + 450: #6980a4, + 500: #5e779d, + 550: #536e97, + 600: #496590, + 650: #3e5b89, + 700: #335283, + 750: #28497c, + 800: #223e69, + 850: #1c3356, + 900: #162844, + 950: #101d31, + 1000: #0a121e, + ), + + 'gray': ( + 0: #fbfbfc, + 50: #f5f5f7, + 100: #ededed, + 150: #e2e2e3, + 200: #d8d8d8, + 300: #c0c0c0, + 400: #a8a8a8, + 500: #909090, + 600: #676767, + 700: #525961, + 800: #3c454e, + 850: #262d35, + 900: #101010, + 950: #0a0a0b, + 1000: #050505, + ), + + 'green': ( + 0: #dcebc6, + 50: #cee3af, + 100: #c1dc99, + 150: #b3d482, + 200: #a5cc6b, + 250: #97c454, + 300: #8abd3e, + 350: #7cb527, + 400: #6ead10, + 450: #67a20f, + 500: #60970e, + 550: #598c0d, + 600: #52810c, + 650: #4b760b, + 700: #446c0a, + 750: #3d6109, + 800: #365608, + 850: #2f4b07, + 900: #284006, + 950: #213505, + 1000: #1a2a04, + ), + + 'red': ( + 0: #f5c2c2, + 50: #f2b2b2, + 100: #f0a2a2, + 150: #ed9292, + 200: #eb8181, + 250: #e87171, + 300: #e66161, + 350: #e35151, + 400: #e04141, + 450: #de3131, + 500: #db2020, + 550: #d91010, + 600: #d60000, + 650: #c20000, + 700: #ad0000, + 750: #990000, + 800: #850000, + 850: #700000, + 900: #5c0000, + 950: #470000, + 1000: #330000, + ), + + 'white': #ffffff, + + 'yellow': ( + 0: #ffefce, + 50: #ffe5af, + 100: #ffdb90, + 150: #ffd071, + 200: #ffc652, + 250: #ffbc33, + 300: #f2b230, + 350: #e5a92e, + 400: #d89f2b, + 450: #cb9629, + 500: #be8c26, + 550: #b18323, + 600: #a47921, + 650: #98701e, + 700: #8b661c, + 750: #7e5d19, + 800: #715316, + 850: #644a14, + 900: #574011, + 950: #4a370f, + 1000: #3d2d0c, + ), +); diff --git a/packages/studip-ui/src/styles/tokens/colors/_content.scss b/packages/studip-ui/src/styles/tokens/colors/_content.scss new file mode 100644 index 0000000..fea72b2 --- /dev/null +++ b/packages/studip-ui/src/styles/tokens/colors/_content.scss @@ -0,0 +1,10 @@ +$theme-bundle: ( + 'light': ( + ), + 'dark': ( + ), + 'hc': ( + ), + 'dhc-adj': ( + ) +); \ No newline at end of file diff --git a/packages/studip-ui/src/styles/tokens/colors/_feedback.scss b/packages/studip-ui/src/styles/tokens/colors/_feedback.scss new file mode 100644 index 0000000..fea72b2 --- /dev/null +++ b/packages/studip-ui/src/styles/tokens/colors/_feedback.scss @@ -0,0 +1,10 @@ +$theme-bundle: ( + 'light': ( + ), + 'dark': ( + ), + 'hc': ( + ), + 'dhc-adj': ( + ) +); \ No newline at end of file diff --git a/packages/studip-ui/src/styles/tokens/colors/_graphic.scss b/packages/studip-ui/src/styles/tokens/colors/_graphic.scss new file mode 100644 index 0000000..fea72b2 --- /dev/null +++ b/packages/studip-ui/src/styles/tokens/colors/_graphic.scss @@ -0,0 +1,10 @@ +$theme-bundle: ( + 'light': ( + ), + 'dark': ( + ), + 'hc': ( + ), + 'dhc-adj': ( + ) +); \ No newline at end of file diff --git a/packages/studip-ui/src/styles/tokens/colors/_structure.scss b/packages/studip-ui/src/styles/tokens/colors/_structure.scss new file mode 100644 index 0000000..fea72b2 --- /dev/null +++ b/packages/studip-ui/src/styles/tokens/colors/_structure.scss @@ -0,0 +1,10 @@ +$theme-bundle: ( + 'light': ( + ), + 'dark': ( + ), + 'hc': ( + ), + 'dhc-adj': ( + ) +); \ No newline at end of file diff --git a/packages/studip-ui/src/styles/tokens/colors/_surface.scss b/packages/studip-ui/src/styles/tokens/colors/_surface.scss new file mode 100644 index 0000000..09e7297 --- /dev/null +++ b/packages/studip-ui/src/styles/tokens/colors/_surface.scss @@ -0,0 +1,48 @@ +$theme-bundle: ( + 'light': ( + brand: ( + 'permanent': 'var(--ref-color-blue-900)', + 'accent': 'var(--ref-color-blue-700)', + ), + canvas: ( + 'default': 'var(--ref-color-gray-50)', + 'subtle': 'var(--ref-color-gray-100)', + ), + card: ( + 'default': 'var(--ref-color-white)', + 'elevated': 'var(--ref-color-white)', + ), + error: ( + 'subtle': 'var(--ref-color-red-100)', + 'default': 'var(--ref-color-red-200)', + ), + info: ( + 'subtle': 'var(--ref-color-blue-100)', + 'default': 'var(--ref-color-blue-200)', + ), + interactive: ( + 'hover': 'var(--ref-color-gray-100)', + 'selected': 'var(--ref-color-blue-50)', + 'active': 'var(--ref-color-blue-100)', + ), + modal: ( + 'default': 'var(--ref-color-white)', + 'overlay': + 'color-mix(in oklab, var(--ref-color-black) var(--ref-opacity-60), transparent)', + ), + neutral: ( + 'subtle': 'var(--ref-color-gray-100)', + 'strong': 'var(--ref-color-gray-300)', + ), + sunken: ( + 'default': 'var(--ref-color-gray-200)', + ), + warning: ( + 'subtle': 'var(--ref-color-yellow-100)', + 'default': 'var(--ref-color-yellow-200)', + ), + ), + 'dark': (), + 'hc': (), + 'dhc-adj': (), +); diff --git a/packages/studip-ui/src/styles/tokens/colors/_text.scss b/packages/studip-ui/src/styles/tokens/colors/_text.scss new file mode 100644 index 0000000..fea72b2 --- /dev/null +++ b/packages/studip-ui/src/styles/tokens/colors/_text.scss @@ -0,0 +1,10 @@ +$theme-bundle: ( + 'light': ( + ), + 'dark': ( + ), + 'hc': ( + ), + 'dhc-adj': ( + ) +); \ No newline at end of file diff --git a/packages/studip-ui/src/styles/tokens/colors/_utils.scss b/packages/studip-ui/src/styles/tokens/colors/_utils.scss new file mode 100644 index 0000000..7401d38 --- /dev/null +++ b/packages/studip-ui/src/styles/tokens/colors/_utils.scss @@ -0,0 +1,10 @@ +// _utils.scss +@use 'sass:map'; + +@function prepare-tokens($theme, $light, $dark, $hc, $dhc-adj) { + @if $theme == 'light' { @return $light; } + @if $theme == 'dark' { @return $dark; } + @if $theme == 'hc' { @return $hc; } + @if $theme == 'dhc' { @return map.merge($dark, $dhc-adj); } + @return (); +} \ No newline at end of file diff --git a/packages/studip-ui/src/styles/tokens/colors/index.scss b/packages/studip-ui/src/styles/tokens/colors/index.scss new file mode 100644 index 0000000..a0cc838 --- /dev/null +++ b/packages/studip-ui/src/styles/tokens/colors/index.scss @@ -0,0 +1,169 @@ +@use 'sass:map'; + +// references +@use 'color' as color; + +$ref-color: color.$ref-color; + +// system (semantics) +@use 'action' as action; +@use 'border' as border; +@use 'brand' as brand; +@use 'content' as content; +@use 'feedback' as feedback; +@use 'graphic' as graphic; +@use 'text' as text; +@use 'structure' as structure; +@use 'surface' as surface; + +$semantic-registry: ( + 'action': action.$theme-bundle, + 'border': border.$theme-bundle, + 'brand': brand.$theme-bundle, + 'content': content.$theme-bundle, + 'feedback': feedback.$theme-bundle, + 'graphic': graphic.$theme-bundle, + 'text': text.$theme-bundle, + 'structure': structure.$theme-bundle, + 'surface': surface.$theme-bundle, +); + +// base colors +$color--black: #000; +$color--blue-1: #28497c; +$color--blue-2: #36598f; +$color--blue-3: #d0d7e3; +$color--gray-1: #101010; +$color--gray-2: #3c454e; +$color--gray-3: #676767; +$color--gray-4: #909090; +$color--gray-5: #d8d8d8; +$color--gray-6: #ededed; +$color--gray-7: #fbfbfc; +$color--green-1: #6ead10; +$color--green-2: #e2efcf; +$color--red-1: #d60000; +$color--red-2: #f7cccc; +$color--white: #fff; +$color--yellow-1: #ffbc33; +$color--yellow-2: #fff2d6; + +// color names + +$color--global-background: $color--white; + +$color--font-primary: $color--gray-1; +$color--font-secondary: $color--gray-3; +$color--font-inactive: $color--gray-3; +$color--font-inverted: $color--white; + +$color--brand-primary: $color--blue-1; +$color--brand-primary-contrast: $color--font-inverted; +$color--brand-secondary: $color--gray-2; +$color--brand-secondary-contrast: $color--font-inverted; + +$color--highlight: $color--blue-1; +$color--highlight-hover: $color--red-1; +$color--highlight-contrast: $color--font-inverted; + +$color--content-link: $color--blue-1; +$color--content-link-hover: $color--red-1; + +$color--sidebar-item: $color--blue-1; +$color--sidebar-item-hover: $color--gray-1; + +$color--main-navigation-background: $color--gray-7; +$color--main-navigation-border: $color--gray-5; +$color--main-navigation-item: $color--blue-1; +$color--main-navigation-item-inactive: $color--gray-4; + +$color--sidebar-marker-active: $color--gray-5; +$color--sidebar-marker-active-navigation: $color--blue-1; +$color--sidebar-marker-active-view: $color--yellow-1; +$color--sidebar-marker-focus: $color--gray-5; +$color--sidebar-marker-hover: $color--gray-5; +$color--sidebar-active: $color--gray-6; +$color--sidebar-focus: $color--gray-6; +$color--sidebar-hover: $color--gray-6; +$color--sidebar-divider: $color--gray-6; + +$color--action-menu-border: $color--gray-5; +$color--action-menu-divider: $color--gray-6; +$color--action-menu-hover: $color--gray-6; +$color--action-menu-marker-hover: $color--gray-5; +$color--action-menu-shadow: $color--gray-5; + +$color--dialog-overlay: $color--gray-1; + +$color--tile-border-focus: $color--gray-4; +$color--tile-border-hover: $color--gray-4; +$color--tile-border: $color--gray-5; +$color--tile-background: $color--gray-7; +$color--tile-background-active: $color--gray-6; +$color--tile-background-focus: $color--gray-6; +$color--tile-background-hover: $color--gray-6; +$color--tile-marker-inactive: $color--gray-4; +$color--tile-marker-active: $color--green-1; +$color--tile-marker-attention: $color--yellow-1; +$color--tile-title-background: $color--gray-6; + +$color--scrollbar-thumb: $color--gray-5; + +$color--content-bar-background: $color--gray-6; + +$color--content-box-border: $color--gray-6; +$color--content-box-header: $color--gray-6; +$color--content-box-background: $color--white; + +$color--fieldset-header: $color--gray-6; +$color--fieldset-border: $color--gray-6; + +$color--tabs-marker-hover: $color--gray-4; +$color--tabs-marker-active: $color--gray-3; + +$color--table-header: $color--gray-6; +$color--table-border: $color--gray-6; +$color--table-focus: $color--gray-6; +$color--table-hover: $color--gray-6; + +$color--button-inactive-background: $color--gray-7; +$color--button-inactive-background-contrast: $color--font-inactive; +$color--button-inactive-border: $color--gray-5; + +$color--radiobuttonset-background: $color--white; +$color--radiobuttonset-background-selected: $color--gray-6; +$color--radiobuttonset-border: $color--gray-6; + +$color--input-field-border: $color--gray-5; +$color--input-field-background: $color--white; + +$color--divider: $color--gray-6; +$color--line: $color--gray-6; + +$color--shadow: $color--gray-4; +$color--focus: $color--gray-4; + +$color--warning: $color--red-1; +$color--warning-secondary: $color--red-2; +$color--warning-contrast: $color--font-inverted; +$color--warning-secondary-contrast: $color--font-primary; + +$color--attention: $color--yellow-1; +$color--attention-secondary: $color--yellow-2; +$color--attention-contrast: $color--font-primary; +$color--attention-secondary-contrast: $color--font-primary; + +$color--good: $color--green-1; +$color--good-secondary: $color--green-2; +$color--good-contrast: $color--font-inverted; +$color--good-secondary-contrast: $color--font-primary; + +$color--info: $color--blue-2; +$color--info-secondary: $color--blue-3; +$color--info-contrast: $color--font-inverted; +$color--info-secondary-contrast: $color--font-primary; + +$color--image-placeholder-background: $color--gray-6; +$color--image-placeholder-icon: $color--gray-4; + +$color-header-inverted: $color--white; diff --git a/packages/studip-ui/src/styles/tokens/components/_button.scss b/packages/studip-ui/src/styles/tokens/components/_button.scss new file mode 100644 index 0000000..e69de29 diff --git a/packages/studip-ui/src/styles/tokens/components/index.scss b/packages/studip-ui/src/styles/tokens/components/index.scss new file mode 100644 index 0000000..e69de29 diff --git a/packages/studip-ui/src/styles/tokens/index.scss b/packages/studip-ui/src/styles/tokens/index.scss index 575e62e..4c5e803 100644 --- a/packages/studip-ui/src/styles/tokens/index.scss +++ b/packages/studip-ui/src/styles/tokens/index.scss @@ -1,9 +1,56 @@ -@use './_colors.scss' as colors; -@use './_spacing.scss' as spacing; -@use './_typography.scss' as typography; +@use 'sass:map'; +@use 'sass:meta'; + +@use 'base' as base; +@use 'colors' as colors; +@use 'opacity' as opacity; +@use 'radius' as radius; +@use 'spacing' as spacing; +@use 'sizes' as sizes; +@use 'typography' as typography; + + + +@mixin generate-tokens($map, $prefix) { + @each $key, $value in $map { + @if meta.type-of($value) == 'map' { + @include generate-tokens($value, #{$prefix}-#{$key}); + } @else { + --#{$prefix}-#{$key}: #{$value}; + } + } +} + +@mixin generate-theme($theme-key) { + @each $name, $bundle in colors.$semantic-registry { + $map: (); + @if $theme-key == 'dhc' { + $dark: map.get($bundle, 'dark'); + $adj: map.get($bundle, 'dhc-adj'); + $map: map.merge($dark, $adj); + } @else { + $map: map.get($bundle, $theme-key); + } + @include generate-tokens($map, 'sys-color-#{$name}'); + } +} :root { + // references + @include generate-tokens(colors.$ref-color, 'ref-color'); + @include generate-tokens(opacity.$ref-opacity, 'ref-opacity'); + @include generate-tokens(sizes.$ref-sizes, 'ref-sizes'); + + // system (semantics) + @include generate-theme('light'); // semantic colors + @include generate-tokens(spacing.$sys-spacing, 'sys-spacing'); + @include generate-tokens(radius.$sys-radius, 'sys-radius'); + + + // base & components + // @include generate-tokens(base.$base, 'base'); + // Farben --color--black: #{colors.$color--black}; @@ -141,8 +188,9 @@ --color--image-placeholder-icon: #{colors.$color--image-placeholder-icon}; --color--header-inverted: #{colors.$color-header-inverted}; - - // Abstände - - // Schriften } + +// once when we will have a dark mode +// [data-theme='dark'] { @include generate-theme('dark'); } +// [data-theme='high-contrast'] { @include generate-theme('hc'); } +// [data-theme='dark-high-contrast'] { @include generate-theme('dhc'); } \ No newline at end of file -- cgit v1.0