storyloco 1.2.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "storyloco",
3
- "version": "1.2.0",
3
+ "version": "1.3.1",
4
4
  "description": "A collection of slick Storyblok field plugins built with Svelte 5, TypeScript, and Tailwind CSS",
5
5
  "keywords": [
6
6
  "storyblok",
@@ -0,0 +1,68 @@
1
+ # Storyblok Field Plugin with "Vanilla" JavaScript
2
+
3
+ This project was generated with `@storyblok/field-plugin-cli`.
4
+
5
+ ## Usage
6
+
7
+ For development, run the application locally with
8
+
9
+ ```shell
10
+ npm run dev
11
+ ```
12
+
13
+ and open the [Sandbox](https://plugin-sandbox.storyblok.com/field-plugin/).
14
+
15
+ To build the project, run
16
+
17
+ ```shell
18
+ npm run build
19
+ ```
20
+
21
+ Deploy the field plugin with the CLI. Issue a [personal access token](https://app.storyblok.com/#/me/account?tab=token), rename `.env.local.example` to `.env.example`, open the file, set the value `STORYBLOK_PERSONAL_ACCESS_TOKEN`, and run
22
+
23
+ ```shell
24
+ npm run deploy
25
+ ```
26
+
27
+ ## Manifest File for Field Plugins
28
+
29
+ The manifest file is a configuration that enhances the functionality of your field plugin. This JSON file, named `field-plugin.config.json` and located in your project's root folder, is optional but highly recommended.
30
+
31
+ The manifest file allows you to configure [options](https://www.storyblok.com/docs/plugins/field-plugins/introduction#options) for your field plugin. When developing your field plugin with the [Sandbox](https://plugin-sandbox.storyblok.com/field-plugin/), the options are applied by default. Also, the deploy command automatically applies the options in production. So, you no longer need to configure the options manually.
32
+
33
+ ### Configuring a Manifest File
34
+
35
+ The options list within the file `field-plugin.config.json` should consist of key-value objects representing the essential options required for your field plugin to function correctly, along with their corresponding values. This is an example of how it should be structured:
36
+
37
+ ```json
38
+ {
39
+ "options": [
40
+ {
41
+ "name": "myPluginInitialValue",
42
+ "value": 100
43
+ }
44
+ ]
45
+ }
46
+ ```
47
+
48
+ Now, you just need to access these options in your code like in the example below:
49
+
50
+ ```js
51
+ console.log(data.options.myPluginInitialValue)
52
+ ```
53
+
54
+ ## Clean up the boilerplate
55
+
56
+ To start from a blank state, delete the following files:
57
+
58
+ - src/components/components.js
59
+
60
+ And search for comments `DELETE THIS BOILERPLATE` comments and delete the code around them.
61
+
62
+ ## Continuous delivery
63
+
64
+ Set up [continuous delivery](https://www.storyblok.com/docs/plugins/field-plugins/continuous-delivery) with the CLI. Define an environmental variable `STORYBLOK_PERSONAL_ACCESS_TOKEN`, and use the `--name` and `--skipPrompts` options as such:
65
+
66
+ ```shell
67
+ npm run deploy --name $NAME --skipPrompts
68
+ ```
@@ -46,7 +46,7 @@
46
46
  <fieldset class="flex gap-2">
47
47
  <Input class="flex-1" bind:value={content.text} oninput={update} />
48
48
  <select
49
- class="rounded outline-none focus-visible:border-ring border-input bg-white border dark:bg-input/30 min-h-11.5"
49
+ class="rounded outline-none focus-visible:border-ring border-input bg-white border bg-input-background min-h-11.5"
50
50
  bind:value={() => content.level, (v) => (content.level = Number(v) as Heading['level'])}
51
51
  onchange={update}
52
52
  >
@@ -0,0 +1,68 @@
1
+ # Storyblok Field Plugin with "Vanilla" JavaScript
2
+
3
+ This project was generated with `@storyblok/field-plugin-cli`.
4
+
5
+ ## Usage
6
+
7
+ For development, run the application locally with
8
+
9
+ ```shell
10
+ npm run dev
11
+ ```
12
+
13
+ and open the [Sandbox](https://plugin-sandbox.storyblok.com/field-plugin/).
14
+
15
+ To build the project, run
16
+
17
+ ```shell
18
+ npm run build
19
+ ```
20
+
21
+ Deploy the field plugin with the CLI. Issue a [personal access token](https://app.storyblok.com/#/me/account?tab=token), rename `.env.local.example` to `.env.example`, open the file, set the value `STORYBLOK_PERSONAL_ACCESS_TOKEN`, and run
22
+
23
+ ```shell
24
+ npm run deploy
25
+ ```
26
+
27
+ ## Manifest File for Field Plugins
28
+
29
+ The manifest file is a configuration that enhances the functionality of your field plugin. This JSON file, named `field-plugin.config.json` and located in your project's root folder, is optional but highly recommended.
30
+
31
+ The manifest file allows you to configure [options](https://www.storyblok.com/docs/plugins/field-plugins/introduction#options) for your field plugin. When developing your field plugin with the [Sandbox](https://plugin-sandbox.storyblok.com/field-plugin/), the options are applied by default. Also, the deploy command automatically applies the options in production. So, you no longer need to configure the options manually.
32
+
33
+ ### Configuring a Manifest File
34
+
35
+ The options list within the file `field-plugin.config.json` should consist of key-value objects representing the essential options required for your field plugin to function correctly, along with their corresponding values. This is an example of how it should be structured:
36
+
37
+ ```json
38
+ {
39
+ "options": [
40
+ {
41
+ "name": "myPluginInitialValue",
42
+ "value": 100
43
+ }
44
+ ]
45
+ }
46
+ ```
47
+
48
+ Now, you just need to access these options in your code like in the example below:
49
+
50
+ ```js
51
+ console.log(data.options.myPluginInitialValue)
52
+ ```
53
+
54
+ ## Clean up the boilerplate
55
+
56
+ To start from a blank state, delete the following files:
57
+
58
+ - src/components/components.js
59
+
60
+ And search for comments `DELETE THIS BOILERPLATE` comments and delete the code around them.
61
+
62
+ ## Continuous delivery
63
+
64
+ Set up [continuous delivery](https://www.storyblok.com/docs/plugins/field-plugins/continuous-delivery) with the CLI. Define an environmental variable `STORYBLOK_PERSONAL_ACCESS_TOKEN`, and use the `--name` and `--skipPrompts` options as such:
65
+
66
+ ```shell
67
+ npm run deploy --name $NAME --skipPrompts
68
+ ```
@@ -1,4 +1,4 @@
1
- <script module lang="ts">
1
+ <script lang="ts">
2
2
  import { createFieldPlugin, type FieldPluginResponse } from '@storyblok/field-plugin'
3
3
  import { onMount } from 'svelte'
4
4
  import { flip } from 'svelte/animate'
@@ -539,7 +539,7 @@
539
539
  </div>
540
540
  {:else}
541
541
  <button
542
- class="p-4 grid grid-cols-[140px_1fr] w-full border border rounded hover:border-primary transition-colors bg-card text-card-foreground items-center justify-items-start gap-5 font-medium"
542
+ class="p-4 grid grid-cols-[140px_1fr] w-full border border-input rounded hover:border-primary transition-colors bg-input-background text-card-foreground items-center justify-items-start gap-5 font-medium"
543
543
  onclick={() => plugin?.actions?.setModalOpen(true)}
544
544
  title="Add video"
545
545
  aria-label="Add video"
@@ -0,0 +1,58 @@
1
+ # Svelte library
2
+
3
+ Everything you need to build a Svelte library, powered by [`sv`](https://npmjs.com/package/sv).
4
+
5
+ Read more about creating a library [in the docs](https://svelte.dev/docs/kit/packaging).
6
+
7
+ ## Creating a project
8
+
9
+ If you're seeing this, you've probably already done this step. Congrats!
10
+
11
+ ```bash
12
+ # create a new project in the current directory
13
+ npx sv create
14
+
15
+ # create a new project in my-app
16
+ npx sv create my-app
17
+ ```
18
+
19
+ ## Developing
20
+
21
+ Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
22
+
23
+ ```bash
24
+ npm run dev
25
+
26
+ # or start the server and open the app in a new browser tab
27
+ npm run dev -- --open
28
+ ```
29
+
30
+ Everything inside `src/lib` is part of your library, everything inside `src/routes` can be used as a showcase or preview app.
31
+
32
+ ## Building
33
+
34
+ To build your library:
35
+
36
+ ```bash
37
+ npm run package
38
+ ```
39
+
40
+ To create a production version of your showcase app:
41
+
42
+ ```bash
43
+ npm run build
44
+ ```
45
+
46
+ You can preview the production build with `npm run preview`.
47
+
48
+ > To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment.
49
+
50
+ ## Publishing
51
+
52
+ Go into the `package.json` and give your package the desired name through the `"name"` option. Also consider adding a `"license"` field and point it to a `LICENSE` file which you can create from a template (one popular option is the [MIT license](https://opensource.org/license/mit/)).
53
+
54
+ To publish your library to [npm](https://www.npmjs.com):
55
+
56
+ ```bash
57
+ npm publish
58
+ ```
@@ -24,7 +24,7 @@
24
24
  bind:this={ref}
25
25
  data-slot="input"
26
26
  class={cn(
27
- 'selection:bg-primary dark:bg-input/30 selection:text-primary-foreground border-input ring-offset-background placeholder:text-muted-foreground shadow-xs flex h-11.5 w-full min-w-0 rounded-md border bg-transparent px-3 pt-1.5 text-sm font-medium outline-none transition-[color,box-shadow] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
27
+ 'selection:bg-primary dark:bg-input-background selection:text-primary-foreground border-input ring-offset-background placeholder:text-muted-foreground shadow-xs flex h-11.5 w-full min-w-0 rounded-md border bg-transparent px-3 pt-1.5 text-sm font-medium outline-none transition-[color,box-shadow] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
28
28
  'focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]',
29
29
  'aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive',
30
30
  classname
@@ -39,9 +39,9 @@
39
39
  bind:this={ref}
40
40
  data-slot="input"
41
41
  class={cn(
42
- 'border-input bg-white selection:bg-primary dark:bg-input/30 selection:text-primary-foreground ring-offset-background placeholder:text-muted-foreground shadow-xs flex h-11.5 w-full min-w-0 rounded-md border px-3 py-1 text-base outline-none transition-[color,box-shadow] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
42
+ 'border-input bg-input-background selection:bg-primary dark:bg-input-background selection:text-primary-foreground ring-offset-background placeholder:text-muted-foreground shadow-xs flex h-11.5 w-full min-w-0 rounded-md border px-3 py-1 text-base outline-none transition-[color,box-shadow] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
43
43
  'focus-visible:border-ring',
44
- 'aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive',
44
+ 'aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive hover:border-primary transition-colors',
45
45
  classname
46
46
  )}
47
47
  {type}
@@ -15,7 +15,7 @@
15
15
  --popover-foreground: oklch(0.129 0.042 264.695);
16
16
  --primary: oklch(54.32% 0.09196 193.854);
17
17
  --primary-foreground: oklch(0.984 0.003 247.858);
18
- --secondary: oklch(0.968 0.007 247.896);
18
+ --secondary: oklch(97.566% 0.00181 249.234);
19
19
  --secondary-foreground: oklch(0.208 0.042 265.755);
20
20
  --muted: oklch(0.968 0.007 247.896);
21
21
  --muted-foreground: oklch(0.554 0.046 257.417);
@@ -24,6 +24,7 @@
24
24
  --destructive: oklch(0.577 0.245 27.325);
25
25
  --border: oklch(0.929 0.013 255.508);
26
26
  --input: oklch(0.929 0.013 255.508);
27
+ --input-background: oklch(1 0 0);
27
28
  --ring: var(--primary);
28
29
  --chart-1: oklch(0.646 0.222 41.116);
29
30
  --chart-2: oklch(0.6 0.118 184.704);
@@ -56,7 +57,7 @@
56
57
  --popover-foreground: oklch(0.984 0.003 247.858);
57
58
  --primary: oklch(54.32% 0.09196 193.854);
58
59
  --primary-foreground: oklch(1 0 0);
59
- --secondary: oklch(0.279 0.041 260.031);
60
+ --secondary: oklch(32.303% 0.00881 285.843);
60
61
  --secondary-foreground: oklch(0.984 0.003 247.858);
61
62
  --muted: oklch(32.303% 0.00881 285.843);
62
63
  --muted-foreground: oklch(66.488% 0.02269 273.875);
@@ -64,7 +65,8 @@
64
65
  --accent-foreground: oklch(0.984 0.003 247.858);
65
66
  --destructive: oklch(0.704 0.191 22.216);
66
67
  --border: oklch(1 0 0 / 10%);
67
- --input: oklch(1 0 0 / 15%);
68
+ --input: oklch(49.548% 0.02083 278.661);
69
+ --input-background: oklch(26.239% 0.00928 285.704);
68
70
  --ring: var(--primary);
69
71
  --chart-1: oklch(0.488 0.243 264.376);
70
72
  --chart-2: oklch(0.696 0.17 162.48);
@@ -108,6 +110,7 @@
108
110
  --color-destructive: var(--destructive);
109
111
  --color-border: var(--border);
110
112
  --color-input: var(--input);
113
+ --color-input-background: var(--input-background);
111
114
  --color-ring: var(--ring);
112
115
  --color-chart-1: var(--chart-1);
113
116
  --color-chart-2: var(--chart-2);
@@ -122,6 +125,8 @@
122
125
  --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
123
126
  --color-sidebar-border: var(--sidebar-border);
124
127
  --color-sidebar-ring: var(--sidebar-ring);
128
+
129
+ --container-xs: 20rem;
125
130
  }
126
131
 
127
132
  @layer base {
@@ -0,0 +1,68 @@
1
+ # Storyblok Field Plugin with "Vanilla" JavaScript
2
+
3
+ This project was generated with `@storyblok/field-plugin-cli`.
4
+
5
+ ## Usage
6
+
7
+ For development, run the application locally with
8
+
9
+ ```shell
10
+ npm run dev
11
+ ```
12
+
13
+ and open the [Sandbox](https://plugin-sandbox.storyblok.com/field-plugin/).
14
+
15
+ To build the project, run
16
+
17
+ ```shell
18
+ npm run build
19
+ ```
20
+
21
+ Deploy the field plugin with the CLI. Issue a [personal access token](https://app.storyblok.com/#/me/account?tab=token), rename `.env.local.example` to `.env.example`, open the file, set the value `STORYBLOK_PERSONAL_ACCESS_TOKEN`, and run
22
+
23
+ ```shell
24
+ npm run deploy
25
+ ```
26
+
27
+ ## Manifest File for Field Plugins
28
+
29
+ The manifest file is a configuration that enhances the functionality of your field plugin. This JSON file, named `field-plugin.config.json` and located in your project's root folder, is optional but highly recommended.
30
+
31
+ The manifest file allows you to configure [options](https://www.storyblok.com/docs/plugins/field-plugins/introduction#options) for your field plugin. When developing your field plugin with the [Sandbox](https://plugin-sandbox.storyblok.com/field-plugin/), the options are applied by default. Also, the deploy command automatically applies the options in production. So, you no longer need to configure the options manually.
32
+
33
+ ### Configuring a Manifest File
34
+
35
+ The options list within the file `field-plugin.config.json` should consist of key-value objects representing the essential options required for your field plugin to function correctly, along with their corresponding values. This is an example of how it should be structured:
36
+
37
+ ```json
38
+ {
39
+ "options": [
40
+ {
41
+ "name": "myPluginInitialValue",
42
+ "value": 100
43
+ }
44
+ ]
45
+ }
46
+ ```
47
+
48
+ Now, you just need to access these options in your code like in the example below:
49
+
50
+ ```js
51
+ console.log(data.options.myPluginInitialValue)
52
+ ```
53
+
54
+ ## Clean up the boilerplate
55
+
56
+ To start from a blank state, delete the following files:
57
+
58
+ - src/components/components.js
59
+
60
+ And search for comments `DELETE THIS BOILERPLATE` comments and delete the code around them.
61
+
62
+ ## Continuous delivery
63
+
64
+ Set up [continuous delivery](https://www.storyblok.com/docs/plugins/field-plugins/continuous-delivery) with the CLI. Define an environmental variable `STORYBLOK_PERSONAL_ACCESS_TOKEN`, and use the `--name` and `--skipPrompts` options as such:
65
+
66
+ ```shell
67
+ npm run deploy --name $NAME --skipPrompts
68
+ ```
@@ -1,26 +1,38 @@
1
1
  <script lang="ts">
2
2
  import { createFieldPlugin, type FieldPluginResponse } from '@storyblok/field-plugin'
3
3
  import { onMount } from 'svelte'
4
- import { snake } from 'radashi'
5
- import Color from 'color'
4
+ import { dash } from 'radashi'
5
+ import { ChevronDownIcon } from '@lucide/svelte'
6
6
  import { cn } from 'shared/utils'
7
+ import { slide } from 'svelte/transition'
7
8
 
8
9
  type Theme = {
9
10
  name: string
10
- hex: string
11
+ primary: string
11
12
  value: string
13
+ secondary?: string
14
+ tertiary?: string
12
15
  }
13
16
 
14
- type Plugin = FieldPluginResponse<string | undefined>
17
+ type Plugin = FieldPluginResponse<Content>
18
+ type Content = string | null
15
19
 
16
20
  let plugin: Plugin | null = $state(null)
17
- let content: string | undefined = $state()
21
+ let content: Content = $state(null)
22
+ let open = $state(false)
18
23
 
19
24
  onMount(() => {
20
- createFieldPlugin<string>({
21
- enablePortalModal: true,
25
+ createFieldPlugin<Content>({
26
+ validateContent(content) {
27
+ if (typeof content !== 'string' || content === 'none') {
28
+ return { content: null }
29
+ }
30
+
31
+ return { content }
32
+ },
22
33
  onUpdateState(state) {
23
34
  plugin = state as Plugin
35
+ if (plugin?.type === 'loaded') content = plugin.data.content
24
36
  },
25
37
  })
26
38
  })
@@ -28,80 +40,103 @@
28
40
  function update() {
29
41
  if (plugin?.type !== 'loaded') return
30
42
  const state = $state.snapshot(content)
31
- plugin.actions.setContent(state)
43
+ plugin.actions.setContent(state === 'none' ? null : state)
32
44
  }
33
45
 
34
46
  const themes: Array<Theme> = $derived.by(() => {
35
47
  if (plugin?.type !== 'loaded') return []
36
48
 
37
49
  return Object.entries(plugin.data.options).map(([key, value]) => {
50
+ const [primary, secondary, tertiary] = value.split(',')
38
51
  return {
39
52
  name: key,
40
- hex: value,
41
- value: snake(key),
53
+ value: `theme-${dash(key)}`,
54
+ primary,
55
+ secondary,
56
+ tertiary,
42
57
  }
43
58
  })
44
59
  })
45
60
 
46
- function is_light(hex: string): boolean {
47
- try {
48
- return Color(hex).isLight()
49
- } catch {
50
- return false
51
- }
52
- }
61
+ const selected = $derived.by(() => {
62
+ if (plugin?.type !== 'loaded') return
63
+
64
+ return themes.find((theme) => theme.value === content)
65
+ })
53
66
  </script>
54
67
 
55
- {#if themes?.length}
56
- <fieldset class="flex items-center gap-2">
57
- {#each themes as { value, name, hex }, index}
58
- {#snippet label(value: string)}
59
- <input
60
- class="sr-only [&:checked+label]:border-[var(--color)] [&:checked+label]:bg-[var(--color-hover)]/10"
61
- id={value}
62
- type="radio"
63
- {value}
64
- bind:group={content}
65
- onchange={update}
66
- />
67
- <label
68
- for={value}
69
- class={cn([
70
- 'flex items-center gap-2 p-3 px-4 border rounded relative border-transparent transition-colors cursor-pointer',
71
- {
72
- 'bg-muted-foreground/10 hover:bg-[var(--color-hover)]/10': value !== 'none',
73
- },
74
- ])}
75
- class:selected={content === value}
76
- style={value === 'none'
77
- ? ''
78
- : `
79
- --color: ${hex};
80
- --color-hover: ${is_light(hex) ? Color(hex).darken(0.8).hex() : hex};
81
- `}
82
- >
83
- {#if value === 'none'}
84
- None
85
- {:else}
86
- <svg
87
- class="size-4"
88
- viewBox="0 0 183 184"
89
- fill="none"
90
- xmlns="http://www.w3.org/2000/svg"
68
+ <div class="@container">
69
+ {#if themes?.length}
70
+ <button
71
+ class="border border-input rounded p-1 px-3.5 bg-input-background min-h-11.5 text-start outline-none focus-visible:border-ring flex items-center justify-between w-full hover:border-primary"
72
+ onclick={() => (open = !open)}
73
+ >
74
+ <span class:text-muted-foreground={!selected}>{selected?.name || 'Select a theme…'}</span>
75
+ <ChevronDownIcon size={16} class={cn({ 'rotate-180': open }, 'transition-transform')} />
76
+ </button>
77
+ {#if open}
78
+ <fieldset
79
+ class="bg-input-background border border-input rounded grid @xs:grid-cols-2 @sm:grid-cols-3 divide-y mt-1 overflow-hidden p-3 gap-3 max-h-54 @xl:max-h-58 overflow-y-auto"
80
+ transition:slide
81
+ >
82
+ {#each themes as { value, name, primary, secondary, tertiary }, index}
83
+ {#snippet label(value: string)}
84
+ <input
85
+ class={cn(
86
+ 'sr-only',
87
+ `
88
+ dark:[&:checked+label]:text-background
89
+ [&:checked+label]:border-primary
90
+ [&:checked+label]:bg-white
91
+
92
+ focus-visible:[&:checked+label]:outline-primary
93
+ focus-visible:[&:checked+label]:outline-2
94
+ focus-visible:[&:checked+label]:outline-offset-2
95
+ `,
96
+ {
97
+ 'dark:[&:checked+label_figure_span]:border-background': value === 'none',
98
+ }
99
+ )}
100
+ id={value}
101
+ type="radio"
102
+ value={value === 'none' ? null : value}
103
+ bind:group={content}
104
+ onchange={update}
105
+ />
106
+ <label
107
+ for={value}
108
+ class="grid justify-center text-xs text-center items-center gap-2 p-3 border rounded relative transition-colors cursor-pointer justify-between hover:bg-primary/10 border-input bg-secondary hover:border-primary transition-colors"
91
109
  >
92
- <path
93
- d="M133.476 6.95414C111.783 -4.24286 86.6097 0.589255 78.855 15.6182L78.816 15.6571C66.9435 3.6288 40.6656 6.34363 23.3116 23.5158C5.97051 40.675 4.10002 65.8488 16.0244 77.8772L15.9855 77.9161C0.865623 85.502 -4.40814 111.871 6.58103 133.693C17.5442 155.49 40.6527 164.492 55.7465 156.88L55.6426 156.984C59.7733 170.623 78.9849 184.483 100.794 183.638C125.189 182.677 145.725 160.14 143.166 143.423C159.858 146.137 178.082 130.017 182.031 105.909C185.967 81.813 174.12 58.8994 157.416 56.1456L157.455 56.1066C165.21 41.0777 155.208 18.1122 133.502 6.92815"
94
- fill="var(--color)"
95
- />
96
- </svg>
97
- {name}
110
+ <figure
111
+ class={cn(
112
+ 'flex justify-center [&>span]:size-10 @xl:[&>span]:size-12 [&>span]:border-white [&>span]:rounded-full [&>span]:border-2 [&>span:not(:first-child)]:-ml-[25%] [&>span]:relative isolate',
113
+ { '[&>span]:border-foreground': value === 'none' }
114
+ )}
115
+ >
116
+ {#if value === 'none'}
117
+ <span></span>
118
+ {:else}
119
+ <span class="z-30" title={primary} style="background-color: {primary}"></span>
120
+ {#if secondary}
121
+ <span class="z-10" title={secondary} style="background-color: {secondary}"
122
+ ></span>
123
+ {/if}
124
+ {#if tertiary}
125
+ <span class="z-10" title={tertiary} style="background-color: {tertiary}"></span>
126
+ {/if}
127
+ {/if}
128
+ </figure>
129
+ <span class="truncate" title={value}>
130
+ {value === 'none' ? 'Default' : name}
131
+ </span>
132
+ </label>
133
+ {/snippet}
134
+ {#if index === 0}
135
+ {@render label('none')}
98
136
  {/if}
99
- </label>
100
- {/snippet}
101
- {#if index === 0}
102
- {@render label('none')}
103
- {/if}
104
- {@render label(value)}
105
- {/each}
106
- </fieldset>
107
- {/if}
137
+ {@render label(value)}
138
+ {/each}
139
+ </fieldset>
140
+ {/if}
141
+ {/if}
142
+ </div>
@@ -0,0 +1,58 @@
1
+ # Svelte library
2
+
3
+ Everything you need to build a Svelte library, powered by [`sv`](https://npmjs.com/package/sv).
4
+
5
+ Read more about creating a library [in the docs](https://svelte.dev/docs/kit/packaging).
6
+
7
+ ## Creating a project
8
+
9
+ If you're seeing this, you've probably already done this step. Congrats!
10
+
11
+ ```bash
12
+ # create a new project in the current directory
13
+ npx sv create
14
+
15
+ # create a new project in my-app
16
+ npx sv create my-app
17
+ ```
18
+
19
+ ## Developing
20
+
21
+ Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
22
+
23
+ ```bash
24
+ npm run dev
25
+
26
+ # or start the server and open the app in a new browser tab
27
+ npm run dev -- --open
28
+ ```
29
+
30
+ Everything inside `src/lib` is part of your library, everything inside `src/routes` can be used as a showcase or preview app.
31
+
32
+ ## Building
33
+
34
+ To build your library:
35
+
36
+ ```bash
37
+ npm run package
38
+ ```
39
+
40
+ To create a production version of your showcase app:
41
+
42
+ ```bash
43
+ npm run build
44
+ ```
45
+
46
+ You can preview the production build with `npm run preview`.
47
+
48
+ > To deploy your app, you may need to install an [adapter](https://svelte.dev/docs/kit/adapters) for your target environment.
49
+
50
+ ## Publishing
51
+
52
+ Go into the `package.json` and give your package the desired name through the `"name"` option. Also consider adding a `"license"` field and point it to a `LICENSE` file which you can create from a template (one popular option is the [MIT license](https://opensource.org/license/mit/)).
53
+
54
+ To publish your library to [npm](https://www.npmjs.com):
55
+
56
+ ```bash
57
+ npm publish
58
+ ```