Skip to content

Commit

Permalink
feat: implement new Figma variable structure (#2124)
Browse files Browse the repository at this point in the history
Refers to #372

changed the variables accordingly (add: cta, focus, border)

---------

Co-authored-by: Lars Rickert <[email protected]>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: ChristianBusshoff <[email protected]>
  • Loading branch information
4 people authored Nov 26, 2024
1 parent dfd092c commit 554833c
Show file tree
Hide file tree
Showing 79 changed files with 1,548 additions and 988 deletions.
8 changes: 8 additions & 0 deletions .changeset/angry-paws-rest.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"sit-onyx": patch
---

feat: implement new figma varialbe structure

- own dark and light colors for each theme
- removed secondary color (visible in: OnyxBadge, OnyxIcon, OnyxTag)
17 changes: 8 additions & 9 deletions .github/workflows/import-figma.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,24 +25,23 @@ jobs:
working-directory: packages/figma-utils

# we need to separately import the themes because they are all needed in different formats and selectors
- name: 🎨 Import onyx variables
- name: 🎨 Import onyx light variables
run: |
pnpm run @sit-onyx/figma-utils import-variables -k "${{ vars.FIGMA_FILE_KEY }}" -t "${{ secrets.FIGMA_TOKEN }}" -d "../sit-onyx/src/styles/variables/themes" -m onyx -f CSS -s ":where(:root), .onyx-theme-default"
pnpm run @sit-onyx/figma-utils import-variables -k "${{ vars.FIGMA_FILE_KEY }}" -t "${{ secrets.FIGMA_TOKEN }}" -d "../sit-onyx/src/styles/variables/themes" -m value onyx-light -f CSS -s ":where(:root), .onyx-theme-default"
working-directory: packages/figma-utils

- name: 🎨 Import additional onyx themes
- name: 🎨 Import onyx dark variables
run: |
pnpm run @sit-onyx/figma-utils import-variables -k "${{ vars.FIGMA_FILE_KEY }}" -t "${{ secrets.FIGMA_TOKEN }}" -d "../sit-onyx/src/styles/variables/themes" -m lidl kaufland twogo -f CSS -s ":where(:root), .onyx-theme-{mode}"
pnpm run @sit-onyx/figma-utils import-variables -k "${{ vars.FIGMA_FILE_KEY }}" -t "${{ secrets.FIGMA_TOKEN }}" -d "../sit-onyx/src/styles/variables/themes" -m onyx-dark -f CSS -s ":where(.dark), .onyx-theme-default-dark"
working-directory: packages/figma-utils

- name: ☀️ Import light variables
- name: 🎨 Import additional onyx light-themes
run: |
pnpm run @sit-onyx/figma-utils import-variables -k "${{ vars.FIGMA_FILE_KEY }}" -t "${{ secrets.FIGMA_TOKEN }}" -d "../sit-onyx/src/styles/variables" -m light -s ":where(:root)"
pnpm run @sit-onyx/figma-utils import-variables -k "${{ vars.FIGMA_FILE_KEY }}" -t "${{ secrets.FIGMA_TOKEN }}" -d "../sit-onyx/src/styles/variables/themes" -m lidl-light kaufland-light digits-light -f CSS -s ":where(:root), .onyx-theme-{mode}"
working-directory: packages/figma-utils

- name: 🌙 Import dark variables
- name: 🎨 Import additional onyx dark-themes
run: |
pnpm run @sit-onyx/figma-utils import-variables -k "${{ vars.FIGMA_FILE_KEY }}" -t "${{ secrets.FIGMA_TOKEN }}" -d "../sit-onyx/src/styles/variables" -m dark -s ":where(.dark)"
pnpm run @sit-onyx/figma-utils import-variables -k "${{ vars.FIGMA_FILE_KEY }}" -t "${{ secrets.FIGMA_TOKEN }}" -d "../sit-onyx/src/styles/variables/themes" -m lidl-dark kaufland-dark digits-dark -f CSS -s ":where(.dark), .onyx-theme-{mode}"
working-directory: packages/figma-utils

- name: 🛠️ Import spacing variables
Expand Down
163 changes: 114 additions & 49 deletions apps/docs/src/.vitepress/components/ColorPalette.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,12 @@ import ColorPaletteValue, { type ColorPaletteValueProps } from "./ColorPaletteVa
import DesignVariable from "./DesignVariable.vue";
import DesignVariableHeader from "./DesignVariableHeader.vue";
const AVAILABLE_TABS = ["Base", "Text & Icons"] as const;
type AvailableTab = (typeof AVAILABLE_TABS)[number];
const props = defineProps<{
name: OnyxColor;
}>();
const AVAILABLE_TABS = ["Base", "Text & Icons", "States"] as const;
type AvailableTab = (typeof AVAILABLE_TABS)[number];
const currentTab = ref<AvailableTab>(AVAILABLE_TABS[0]);
/** Speaking names for base color steps. */
Expand All @@ -26,50 +25,108 @@ const whiteTextColor = "var(--onyx-color-base-grayscale-white)";
/**
* Available color steps to display for the currently active tab (e.g. 100-900 for base colors).
*/
function getBaseColorSteps(name: OnyxColor): ColorPaletteValueProps[] {
return Array.from({ length: 9 }, (_, index) => {
const step = (index + 1) * 100;
return {
description: step,
name: baseStepNames[step],
color: `var(--onyx-color-base-${name}-${step})`,
textColor: step < 500 ? `var(--onyx-color-text-icons-${name}-bold)` : whiteTextColor,
};
});
}
function getTextAndIconColorSteps(name: OnyxColor): ColorPaletteValueProps[] {
const textColor =
name === "neutral" ? whiteTextColor : `var(--onyx-color-text-icons-${name}-bold)`;
return [
{ description: "soft", color: `var(--onyx-color-text-icons-${name}-soft)`, textColor },
{ description: "medium", color: `var(--onyx-color-text-icons-${name}-medium)`, textColor },
{
description: "intense",
color: `var(--onyx-color-text-icons-${name}-intense)`,
textColor: whiteTextColor,
},
name === "neutral"
? {
description: "inverted",
color: `var(--onyx-color-text-icons-inverted)`,
textColor: `var(--onyx-color-text-icons-intense)`,
showBorder: true,
}
: {
description: "bold",
color: `var(--onyx-color-text-icons-${name}-bold)`,
textColor: whiteTextColor,
},
];
}
function getStateColorSteps(name: OnyxColor): ColorPaletteValueProps[] {
type ExtendedOnyxColor = OnyxColor | "default";
const mappings: {
cta: Partial<Record<ExtendedOnyxColor, string>>;
border: Partial<Record<ExtendedOnyxColor, string>>;
borderHover: Partial<Record<ExtendedOnyxColor, string>>;
focus: Partial<Record<ExtendedOnyxColor, string>>;
} = {
cta: { primary: "default", danger: "invalid", neutral: "disabled" },
border: { danger: "invalid", default: name },
borderHover: { danger: "invalid-hover", neutral: "disabled", default: `${name}-hover` },
focus: { danger: "invalid", default: name },
};
const cta = mappings.cta[name] || null;
const border = mappings.border[name] || name;
const borderHover = mappings.borderHover[name] || mappings.borderHover.default;
const focus = mappings.focus[name] || mappings.focus.default;
const textColor =
name === "neutral" ? `var(--onyx-color-text-icons-${name}-bold)` : whiteTextColor;
return [
name === "primary" || name === "danger" || name === "neutral"
? {
description: name === "neutral" ? "cta-disabled" : "cta",
color: `var(--onyx-color-component-cta-${cta})`,
textColor,
}
: null,
name === "primary" || name === "danger"
? {
description: "cta-hover",
color: `var(--onyx-color-component-cta-${cta}-hover)`,
textColor,
}
: null,
{
description: name === "neutral" ? "border-neutral" : "border",
color: `var(--onyx-color-component-border-${border})`,
textColor,
},
{
description: name === "neutral" ? "border-disabled" : "border-hover",
color: `var(--onyx-color-component-border-${borderHover})`,
textColor,
},
{
description: name === "neutral" ? "focus-neutral" : "focus",
color: `var(--onyx-color-component-focus-${focus})`,
textColor: `var(--onyx-color-text-icons-${name}-bold)`,
},
].filter(Boolean) as ColorPaletteValueProps[];
}
const colorSteps = computed<ColorPaletteValueProps[]>(() => {
if (currentTab.value === "Base") {
return Array.from({ length: 9 }, (_, index) => {
const step = (index + 1) * 100;
return {
description: step,
name: baseStepNames[step],
color: `var(--onyx-color-base-${props.name}-${step})`,
textColor: step < 500 ? `var(--onyx-color-text-icons-${props.name}-bold)` : whiteTextColor,
};
});
} else {
const textColor =
props.name === "neutral" ? whiteTextColor : `var(--onyx-color-text-icons-${props.name}-bold)`;
return [
{
description: "soft",
color: `var(--onyx-color-text-icons-${props.name}-soft)`,
textColor,
},
{
description: "medium",
color: `var(--onyx-color-text-icons-${props.name}-medium)`,
textColor,
},
{
description: "intense",
color: `var(--onyx-color-text-icons-${props.name}-intense)`,
textColor: whiteTextColor,
},
props.name === "neutral"
? {
description: "inverted",
color: `var(--onyx-color-text-icons-inverted)`,
textColor: `var(--onyx-color-text-icons-intense)`,
showBorder: true,
}
: {
description: "bold",
color: `var(--onyx-color-text-icons-${props.name}-bold)`,
textColor: whiteTextColor,
},
];
switch (currentTab.value) {
case "Base":
return getBaseColorSteps(props.name);
case "Text & Icons":
return getTextAndIconColorSteps(props.name);
default:
return getStateColorSteps(props.name);
}
});
Expand All @@ -80,13 +137,17 @@ let copyTimeout: ReturnType<typeof setTimeout> | undefined;
* Copies the given color to the clipboard and sets the `copiedColor` to its value for 3 seconds.
*/
const handleCopy = async (color: string) => {
const cssVariable = color.match(/var\(--(.*)\)/)?.[1] ?? color;
await navigator.clipboard.writeText(color);
copiedColor.value = color.replace(/var\(--(.*)\)/, "$1");
copiedColor.value = cssVariable;
// if multiple colors are copied quickly after each other, we need to
// clear the previous timeout so we prevent race-conditions
clearTimeout(copyTimeout);
copyTimeout = setTimeout(() => (copiedColor.value = ""), 3000);
copyTimeout = setTimeout(() => {
copiedColor.value = "";
}, 3000);
};
</script>

Expand All @@ -95,7 +156,11 @@ const handleCopy = async (color: string) => {
<DesignVariableHeader
v-model="currentTab"
:headline="capitalize(props.name)"
:tabs="AVAILABLE_TABS"
:tabs="
props.name === 'warning' || props.name === 'info'
? AVAILABLE_TABS.slice(0, -1)
: AVAILABLE_TABS
"
/>

<div class="palette__content">
Expand Down
10 changes: 2 additions & 8 deletions apps/docs/src/.vitepress/components/OnyxColorPalettes.vue
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<script lang="ts" setup>
import { ONYX_COLORS } from "sit-onyx";
import { useData } from "vitepress";
import ColorPalette from "./ColorPalette.vue";
import DesignVariableBadge from "./DesignVariableBadge.vue";
Expand All @@ -12,14 +13,7 @@ const { isDark } = useData();
<DesignVariableBadge text="Light mode" :active="!isDark" @click="isDark = false" />
<DesignVariableBadge text="Dark mode" :active="isDark" @click="isDark = true" />
</div>

<ColorPalette name="primary" />
<ColorPalette name="secondary" />
<ColorPalette name="neutral" />
<ColorPalette name="danger" />
<ColorPalette name="warning" />
<ColorPalette name="success" />
<ColorPalette name="info" />
<ColorPalette v-for="color in ONYX_COLORS" :key="color" :name="color" />
</div>
</template>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,6 @@ const primaryColors = Array.from({ length: 9 }, (_, index) => {
return `var(--onyx-color-base-primary-${(index + 1) * 100})`;
});
const secondaryColors = Array.from({ length: 9 }, (_, index) => {
return `var(--onyx-color-base-secondary-${(index + 1) * 100})`;
});
const neutralColors = Array.from({ length: 9 }, (_, index) => {
return `var(--onyx-color-base-neutral-${(index + 1) * 100})`;
});
Expand Down Expand Up @@ -60,7 +56,6 @@ const infoColors = Array.from({ length: 9 }, (_, index) => {

<div class="theme__colors theme__colors--themed">
<ColorStrip name="primary" :colors="primaryColors" />
<ColorStrip name="secondary" :colors="secondaryColors" />
<ColorStrip name="neutral" :colors="neutralColors" />
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion apps/docs/src/basics/colors.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ To have access to the color variable set for your implementation, please visit t

## Roles of themed colors

Themed colors reflect the brand's identity, adapting their main colors. While primary and secondary colors vary between the themes, the usage of them is constant.
Themed colors reflect the brand's identity, adapting their main colors. While primary colors vary between the themes, the usage of them is constant.

Primary colors highlight call-to-action elements and direct the focus of the user to the most important interactions. Brand-neutrals are used in the background and secondary actions, providing a subtle backdrop that allows primary colors to shine.

Expand Down
3 changes: 2 additions & 1 deletion apps/docs/src/development/theming.data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ export default defineLoader({
load(watchedFiles): Data {
return {
themes: watchedFiles
.map((filePath) => filePath.split("/").at(-1)!.replace(".css", ""))
.filter((theme) => theme.includes("light"))
.map((filePath) => filePath.split("/").at(-1)!.replace("-light.css", ""))
.sort((a, b) => {
if (a === "onyx") return -1;
if (b === "onyx") return 1;
Expand Down
8 changes: 6 additions & 2 deletions apps/docs/src/development/theming.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,18 @@ The following color themes are built-in to onyx:
</li>
</ul>

To use a different theme, add the corresponding import to your `main.ts` file (example for the lidl theme):
To use a different theme, add the corresponding imports to your `main.ts` file (example for the lidl theme):
:::info
Make sure to import both the light and dark variants of the theme.
:::

::: code-group

```ts [main.ts]
// import "sit-onyx/styles.css";
// make sure to import the theme AFTER the general "sit-onyx/styles.css" file!
import "sit-onyx/themes/lidl.css";
import "sit-onyx/themes/lidl-light.css";
import "sit-onyx/themes/lidl-dark.css";
```

:::
Expand Down
1 change: 1 addition & 0 deletions packages/figma-utils/src/types/figma.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export type Variable = {
name: string;
variableCollectionId: string;
hiddenFromPublishing: boolean;
deletedButReferenced?: boolean;
valuesByMode: Record<string, VariableValue>;
};

Expand Down
7 changes: 6 additions & 1 deletion packages/figma-utils/src/variables/parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,12 @@ export const parseFigmaVariables = (
*/
Object.values(apiResponse.meta.variables).forEach((variable) => {
const collection = apiResponse.meta.variableCollections[variable.variableCollectionId];
if (variable.hiddenFromPublishing || collection.hiddenFromPublishing) return;
if (
variable.hiddenFromPublishing ||
variable.deletedButReferenced ||
collection.hiddenFromPublishing
)
return;

// parse variable value for every mode
Object.values(collection.modes).forEach((mode) => {
Expand Down
3 changes: 2 additions & 1 deletion packages/nuxt/src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ export default defineNuxtModule<ModuleOptions>({
nuxt.options.css.push("sit-onyx/style.css");

if (options.theme !== "onyx") {
nuxt.options.css.push(`sit-onyx/themes/${options.theme}.css`);
nuxt.options.css.push(`sit-onyx/themes/${options.theme}-light.css`);
nuxt.options.css.push(`sit-onyx/themes/${options.theme}-dark.css`);
}

if (!options.disableGlobalStyles) {
Expand Down
Loading

0 comments on commit 554833c

Please sign in to comment.