Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Theme generator #192

Merged
merged 28 commits into from
Jan 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
099d2d9
Rename `cssVars` action to `styleVars` and do not prefix properties w…
techniq Jan 7, 2024
db49328
[SelectField] Fix toggling display of options menu using toggleIcon. …
techniq Jan 7, 2024
c585b15
[SelectField] Add `stepper` prop to iterate through options (like `Me…
techniq Jan 7, 2024
00c7dce
[MenuField] Expose `selected` option via prop (similar to `SelectField`)
techniq Jan 7, 2024
17427fe
[SelectField Add stepper example
techniq Jan 7, 2024
b43f0cc
Move `processThemeColors()` from tailwind plugin to $lib/styles/theme…
techniq Jan 7, 2024
07b9bdc
Update skeleton.ts to match skeleton.cjs (to be removed)
techniq Jan 7, 2024
bd7f7bb
Beginning work of theme generator
techniq Jan 7, 2024
4131034
Read themes from `themes.json` file for both tailwind config and them…
techniq Jan 7, 2024
2432baa
Add "Copy all" daisy and skeleton options
techniq Jan 7, 2024
31e7d17
Use <ThemeSelect> or <ThemeSwitch> based on more than 1 light/dark theme
techniq Jan 7, 2024
9cce80e
Fix skeleton dark themes after refactor
techniq Jan 7, 2024
cb502d8
Add explicit daisy themeName list to hopefully fix build (similar to …
techniq Jan 7, 2024
d1d0dc0
Set initial theme selections (fix reactivity infinite loop)
techniq Jan 7, 2024
1891138
[SelectField] Use `selectValue(...)` instead of `value = ...` so `cha…
techniq Jan 7, 2024
e86f74c
Change light/dark preview based on which input was last changed
techniq Jan 7, 2024
16110f6
Support overriding doc themes wtih generator (custom) themes
techniq Jan 8, 2024
2c7467d
Fix setting `prefers-color-scheme: dark` override
techniq Jan 9, 2024
0df2af4
Use a local copy of Skeleton themes to fix Cloudflare build (work aro…
techniq Jan 9, 2024
5c5b575
Improve handling of `-50` shade when `-100` exists (ex. Skeleton)
techniq Jan 10, 2024
a6f34b1
Update site dark/light mode with preview for better experience (previ…
techniq Jan 10, 2024
1f86d07
Support custom Ior exisitng) theme editing
techniq Jan 10, 2024
9f3920a
Add state colors and support showing/hiding optoinal colors
techniq Jan 10, 2024
b46d5c4
Add "Copy all themes" menu item
techniq Jan 10, 2024
645ccd8
[ColorField] Support `hex` entry
techniq Jan 10, 2024
b7c74d8
Register all themes (daisy + skeleton)
techniq Jan 10, 2024
cfce2b8
Format files (fix lint error)
techniq Jan 10, 2024
50a6b99
Add changeset
techniq Jan 10, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/cool-hotels-own.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"svelte-ux": patch
---

[SelectField] Add `stepper` prop to iterate through options (like `MenuField`)
5 changes: 5 additions & 0 deletions .changeset/fair-trees-sparkle.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"svelte-ux": patch
---

[MenuField] Expose `selected` option via prop (similar to `SelectField`)
5 changes: 5 additions & 0 deletions .changeset/quick-carrots-grab.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"svelte-ux": minor
---

Add theme selection/creation page and simplify loading themes
5 changes: 5 additions & 0 deletions .changeset/selfish-hounds-dance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"svelte-ux": patch
---

[SelectField] Fix toggling display of options menu using toggleIcon. Support hiding toggleIcon (`<SelectField toggleIcon={null} />
5 changes: 5 additions & 0 deletions .changeset/yellow-nails-vanish.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'svelte-ux': minor
---

Rename `cssVars` action to `styleVars` and do not prefix properties with `--` by default (more flexible)
1 change: 1 addition & 0 deletions packages/svelte-ux/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"@sveltejs/kit": "^1.30.3",
"@sveltejs/package": "^2.2.5",
"@tailwindcss/typography": "^0.5.10",
"@types/culori": "^2.0.4",
"@types/d3-array": "^3.2.1",
"@types/d3-scale": "^4.0.8",
"@types/lodash-es": "^4.17.12",
Expand Down
2 changes: 1 addition & 1 deletion packages/svelte-ux/src/lib/actions/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
export * from './cssVars';
export * from './dataBackground';
export * from './input';
export * from './layout';
Expand All @@ -9,4 +8,5 @@ export * from './portal';
export * from './scroll';
export * from './spotlight';
export * from './sticky';
export * from './styleProps';
export * from './table';
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import type { Action } from 'svelte/action';

type CSSProps = { [key: string]: string | number | boolean | null | undefined };

export const cssVars: Action<HTMLElement, CSSProps> = (node, props) => {
export const styleProps: Action<HTMLElement, CSSProps> = (node, props) => {
Object.entries(props ?? {}).forEach(([key, value]) => {
// Ignore if null or undefined
if (value != null) {
value = typeof value === 'boolean' ? (value ? 1 : 0) : value;
node.style.setProperty(`--${key}`, `${value}`);
node.style.setProperty(key, `${value}`);
}
});

Expand All @@ -17,13 +17,13 @@ export const cssVars: Action<HTMLElement, CSSProps> = (node, props) => {
update(newProps: CSSProps) {
const newKeys = Object.keys(newProps);
Object.keys(lastProps)
.filter((name) => !newKeys.includes(name))
.forEach((name) => node.style.removeProperty(`--${name}`));
.filter((key) => !newKeys.includes(key))
.forEach((key) => node.style.removeProperty(key));

Object.entries(newProps).forEach(([key, value]) => {
// Ignore if null or undefined
if (value != null) {
node.style.setProperty(`--${key}`, `${value}`);
node.style.setProperty(key, `${value}`);
}
if (props) {
delete props[key];
Expand Down
27 changes: 10 additions & 17 deletions packages/svelte-ux/src/lib/components/Grid.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
<script lang="ts">
import { cssVars } from '../actions/cssVars';
export let columns = 0;
export let gap = 0;
export let columnGap = gap;
Expand Down Expand Up @@ -38,28 +36,23 @@
templateColumns ??
template ??
(autoColumns ? `repeat(auto-fill, minmax(${autoColumns}, 1fr))` : `repeat(${columns}, 1fr)`);
$: styleVars = {
templateColumns: templateColumnsResolved,
templateRows,
gap,
columnGap,
rowGap,
autoFlow,
items, // TODO: Map start: flex-start?, end: flex-end?
justify, // TODO: Map start: flex-start?, end: flex-end?, between: space-between, around: space-around, evenly: space-evenly
justifyItems, // TODO: Map start: flex-start?, end: flex-end?, between: space-between, around: space-around, evenly: space-evenly
content, // TODO: Map start: flex-start?, end: flex-end?, between: space-between, around: space-around, evenly: space-evenly
// place, // TODO: Map start: flex-start?, end: flex-end?, between: space-between, around: space-around, evenly: space-evenly
};
</script>

<div
use:cssVars={styleVars}
class="Grid"
class:grid={!inline}
class:inline-grid={inline}
class:stack
style:--templateColumns={templateColumnsResolved}
style:--templateRows={templateRows}
style:--gap={gap}
style:--columnGap={columnGap}
style:--rowGap={rowGap}
style:--autoFlow={autoFlow}
style:--items={items}
style:--justify={justify}
style:--justifyItems={justifyItems}
style:--content={content}
on:click
{...$$restProps}
>
Expand Down
1 change: 1 addition & 0 deletions packages/svelte-ux/src/lib/components/MenuField.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
const settingsClasses = getComponentClasses('MenuField');
let open = false;
export let selected: any = undefined;
$: selected = options?.find((x) => x.value === value);
$: previous = () => {
Expand Down
72 changes: 65 additions & 7 deletions packages/svelte-ux/src/lib/components/SelectField.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { createEventDispatcher, type ComponentProps, type ComponentEvents } from 'svelte';
import type { Placement } from '@floating-ui/dom';
import { mdiChevronDown, mdiClose } from '@mdi/js';
import { mdiChevronDown, mdiChevronLeft, mdiChevronRight, mdiClose } from '@mdi/js';
import Logger from '../utils/logger';
import { autoFocus, selectOnFocus } from '$lib/actions';
Expand Down Expand Up @@ -36,7 +36,8 @@
export let disabled: boolean = false;
export let readonly: boolean = false;
export let icon: IconInput = undefined;
export let toggleIcon: IconInput = mdiChevronDown;
export let inlineOptions = false;
export let toggleIcon: IconInput = !inlineOptions ? mdiChevronDown : null;
export let closeIcon: IconInput = mdiClose;
export let activeOptionIcon: boolean = false;
export let clearable = true;
Expand All @@ -53,6 +54,9 @@
]
: undefined;
/** If true, show left/right buttons to step through options */
export let stepper = false;
let originalIcon = icon;
export let scrollIntoView: Partial<ScrollIntoViewOptions> = {};
Expand All @@ -78,7 +82,6 @@
export let resize = true;
export let disableTransition = false;
export let menuProps: ComponentProps<Menu> | undefined = undefined;
export let inlineOptions = false;
$: filteredOptions = options ?? [];
let searchText = '';
Expand Down Expand Up @@ -157,6 +160,7 @@
// Elements
let inputEl: HTMLInputElement | null = null;
let menuOptionsEl: HTMLDivElement;
let selectFieldEl: HTMLButtonElement;
// UI state
export let open = false;
Expand Down Expand Up @@ -219,7 +223,9 @@
fe.relatedTarget instanceof HTMLElement &&
!menuOptionsEl?.contains(fe.relatedTarget) && // TODO: Oddly Safari does not set `relatedTarget` to the clicked on menu option (like Chrome and Firefox) but instead appears to take `tabindex` into consideration. Currently resolves to `.options` after setting `tabindex="-1"
fe.relatedTarget !== menuOptionsEl?.offsetParent && // click on scroll bar
!fe.relatedTarget.closest('menu > [slot=actions]') // click on action item
!fe.relatedTarget.closest('menu > [slot=actions]') && // click on action item
!selectFieldEl?.contains(fe.relatedTarget) && // click within <SelectField> (ex. toggleIcon)
fe.relatedTarget !== selectFieldEl // click on SelectField itself
) {
hide('blur');
} else {
Expand Down Expand Up @@ -358,6 +364,28 @@
return option;
}
$: previous = () => {
const index = options.findIndex((o) => o.value === value);
if (index === 0 || index === -1) {
// If first item, or no selected value yet, return last item
return options[options.length - 1].value;
} else {
// Previous item
return options[index - 1].value;
}
};
$: next = () => {
const index = options.findIndex((x) => x.value === value);
if (index === options.length - 1) {
// First value
return options[0].value;
} else {
// Next value
return options[index + 1].value;
}
};
function clear() {
logger.info('clear');
selectOption(null);
Expand All @@ -374,6 +402,7 @@
classes.root,
$$props.class
)}
bind:this={selectFieldEl}
on:click={onClick}
>
<TextField
Expand Down Expand Up @@ -403,7 +432,21 @@
aria-autocomplete={!inlineOptions ? 'list' : undefined}
{...$$restProps}
>
<slot slot="prepend" name="prepend" />
<span slot="prepend">
{#if stepper}
<Button
icon={mdiChevronLeft}
on:click={(e) => {
e.stopPropagation();
logger.debug('step left clicked');
selectValue(previous());
}}
class="mr-2"
size="sm"
/>
{/if}
<slot name="prepend" />
</span>

<span slot="append" class="flex items-center">
<slot name="append" />
Expand All @@ -424,14 +467,29 @@
clear();
}}
/>
{:else if !inlineOptions}
{:else if toggleIcon}
<Button
icon={toggleIcon}
class="text-surface-content/50 p-1 transform {open ? 'rotate-180' : ''}"
tabindex="-1"
on:click={() => {
on:click={(e) => {
e.stopPropagation();
logger.debug('toggleIcon clicked');
open ? hide() : show();
}}
/>
{/if}

{#if stepper}
<Button
icon={mdiChevronRight}
on:click={(e) => {
e.stopPropagation();
logger.debug('step right clicked');
selectValue(next());
}}
class="mr-2"
size="sm"
/>
{/if}
</span>
Expand Down
17 changes: 6 additions & 11 deletions packages/svelte-ux/src/lib/components/Steps.svelte
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
<script lang="ts">
import { cssVars } from '../actions/cssVars';
export let items: any[];
export let lineGap = 4;
// binded
let circleSize = 0;
$: styleVars = {
circleSize,
lineTop: `${circleSize + lineGap}px`,
lineBottom: `${lineGap}px`,
lineOffset: `${circleSize / 2}px`,
};
</script>

<ol use:cssVars={styleVars}>
<ol
style:--circleSize={circleSize}
style:--lineTop="{circleSize + lineGap}px"
style:--lineBottom="{lineGap}px"
style:--lineOffset="{circleSize / 2}px"
>
{#each items as item, index}
<li class="step relative flex gap-4 pb-10">
<div bind:clientWidth={circleSize}>
Expand Down
Loading