@placeholderco/placeholder-ui 1.0.10 → 1.0.11

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.
@@ -1,148 +1,113 @@
1
1
  <script lang="ts">
2
- // Sourced from https://svelte.dev/playground/d65a4e9f0ae74d1eb1b08d13e428af32?version=5.36.16, and updated from there
3
- import FormGroup from './FormGroup.svelte';
2
+ import FormGroup from "./FormGroup.svelte";
4
3
 
5
- interface Props {
6
- label: string;
7
- required?: boolean;
8
- checked: boolean;
9
- disabled?: boolean;
10
- description?: string;
4
+ interface Props {
5
+ label: string;
6
+ required?: boolean;
7
+ checked: boolean;
8
+ disabled?: boolean;
11
9
  containerClass?: string;
12
10
  switchClass?: string;
13
11
  onchange?: (value: boolean) => void;
14
12
  showError?: boolean;
15
- }
16
-
17
- let { label, required = false, checked = $bindable(), disabled = false, containerClass, switchClass, onchange, showError }: Props = $props();
18
-
19
- function handleClick(event: Event){
20
- const target = event.target as HTMLElement
21
-
22
- const state = target.getAttribute('aria-checked')
13
+ }
23
14
 
24
- checked = !(state === 'true')
15
+ let {
16
+ label,
17
+ required = false,
18
+ checked = $bindable(),
19
+ disabled = false,
20
+ containerClass,
21
+ switchClass,
22
+ onchange,
23
+ showError,
24
+ }: Props = $props();
25
+
26
+ function handleClick(event: Event) {
27
+ const target = event.target as HTMLElement;
28
+ const state = target.getAttribute("aria-checked");
29
+ checked = !(state === "true");
25
30
  onchange?.(checked);
26
31
  }
27
32
  </script>
28
33
 
29
34
  <div class="switch-container {containerClass}">
30
- <FormGroup {required} {label}>
31
- <div class="s s--slider {switchClass} {required ? 'required' : ''}
32
- {showError ? 'error' : ''}
33
- {disabled ? 'disabled' : ''}">
34
- <button
35
- role="switch"
36
- aria-checked={checked}
37
- onclick={handleClick}
38
- aria-labelledby="form-{label}"
39
- class="{disabled ? 'disabled' : ''}"
40
- {disabled}
41
- >
42
- </button>
43
- </div>
44
- <span class="slider"></span>
45
- </FormGroup>
35
+ <FormGroup {required} {label}>
36
+ <div
37
+ class="switch-track {switchClass}"
38
+ class:error={showError}
39
+ class:disabled
40
+ >
41
+ <button
42
+ role="switch"
43
+ aria-checked={checked}
44
+ aria-labelledby="form-{label}"
45
+ onclick={handleClick}
46
+ {disabled}
47
+ ></button>
48
+ </div>
49
+ </FormGroup>
46
50
  </div>
47
51
 
48
-
49
52
  <style>
50
- :root .switch-container {
51
- --switch-accent-color: var(--pui-color-primary);
52
- --switch-track-color: var(--pui-border-disabled);
53
- }
53
+ .switch-container {
54
+ --switch-track-color: var(--pui-border-disabled);
55
+ }
54
56
 
55
57
  :global(.dark) .switch-container {
56
- --switch-accent-color: var(--pui-color-primary);
57
58
  --switch-track-color: var(--pui-color-gray-600);
58
59
  }
59
60
 
60
- .disabled button {
61
- cursor: not-allowed;
62
- }
63
-
64
-
65
- /* Inner Design Option */
66
- .s--inner button {
67
- padding: var(--pui-spacing-2);
68
- background-color: var(--pui-color-white);
69
- border: 1px solid var(--switch-track-color);
70
- }
71
-
72
- .s--inner button:focus {
73
- outline: var(--pui-color-primary) solid 1px;
74
- }
75
-
76
- /* Slider Design Option */
77
-
78
- .s--slider {
61
+ .switch-track {
79
62
  display: flex;
80
63
  align-items: center;
81
64
  }
82
65
 
83
- .s--slider button {
66
+ button {
84
67
  width: 3em;
85
68
  height: 1.6em;
86
69
  position: relative;
87
70
  margin: 0 0 0 var(--pui-spacing-2);
71
+ padding: 0;
88
72
  background: var(--switch-track-color);
89
73
  border: none;
74
+ border-radius: var(--pui-radius-3xl);
75
+ cursor: pointer;
76
+ transition: background-color var(--pui-transition-fast)
77
+ var(--pui-ease-in-out);
90
78
  }
91
79
 
92
- .s--slider button::before {
93
- content: '';
80
+ button::before {
81
+ content: "";
94
82
  position: absolute;
95
83
  width: 1.3em;
96
84
  height: 1.3em;
97
- background: var(--pui-color-white);
98
- top: 0.13em;
85
+ top: 0.15em;
99
86
  right: 1.5em;
87
+ background: var(--pui-color-white);
88
+ border-radius: var(--pui-radius-full);
100
89
  transition: transform var(--pui-transition-slow) var(--pui-ease-in-out);
101
90
  }
102
91
 
103
- .s--slider button[aria-checked='true']{
92
+ button[aria-checked="true"] {
104
93
  background-color: var(--pui-color-primary);
105
94
  }
106
95
 
107
- .s--slider button[aria-checked='true']::before{
96
+ button[aria-checked="true"]::before {
108
97
  transform: translateX(1.3em);
109
- transition: transform var(--pui-transition-slow) var(--pui-ease-in-out);
110
98
  }
111
99
 
112
- .s--slider button:focus {
113
- outline: 1px solid var(--pui-color-primary);
100
+ button:focus-visible {
101
+ outline: 2px solid var(--pui-color-primary);
114
102
  outline-offset: var(--pui-focus-ring-offset);
115
103
  }
116
104
 
117
- /* Multi Design Option */
118
-
119
- /* Based on suggestions from Sara Soueidan https://www.sarasoueidan.com/blog/toggle-switch-design/
120
- and this example from Scott O'hara https://codepen.io/scottohara/pen/zLZwNv */
121
-
122
- .s--multi .group-container {
123
- border: none;
124
- padding: 0;
125
- white-space: nowrap;
105
+ .disabled button {
106
+ opacity: 0.5;
107
+ cursor: not-allowed;
126
108
  }
127
109
 
128
-
129
- /* gravy */
130
-
131
- /* Inner Design Option */
132
-
133
- .s--inner button:focus {
134
- outline-offset: var(--pui-focus-ring-offset);
135
- border-radius: var(--pui-radius-sm);
110
+ .error button {
111
+ outline: 1px solid var(--pui-text-danger);
136
112
  }
137
-
138
- /* Slider Design Option */
139
- .s--slider button {
140
- border-radius: var(--pui-radius-3xl);
141
- }
142
-
143
- .s--slider button::before {
144
- border-radius: var(--pui-radius-full);
145
- }
146
-
147
-
148
- </style>
113
+ </style>
@@ -3,7 +3,6 @@ interface Props {
3
3
  required?: boolean;
4
4
  checked: boolean;
5
5
  disabled?: boolean;
6
- description?: string;
7
6
  containerClass?: string;
8
7
  switchClass?: string;
9
8
  onchange?: (value: boolean) => void;
@@ -14,6 +14,8 @@
14
14
  inContainer?: boolean;
15
15
  middleSection?: Snippet;
16
16
  rightSection?: Snippet;
17
+ /** Icons displayed to the left of the ThemeSwitcher, visible even when collapsed on mobile */
18
+ iconSection?: Snippet;
17
19
  /** Enable responsive collapse to burger menu on small screens (default: true) */
18
20
  responsive?: boolean;
19
21
  /** Breakpoint in pixels at which the navbar collapses (default: 768) */
@@ -34,6 +36,7 @@
34
36
  inContainer = false,
35
37
  middleSection = undefined,
36
38
  rightSection = undefined,
39
+ iconSection = undefined,
37
40
  responsive = true,
38
41
  responsiveBreakpoint = 768,
39
42
  // Drawer button options
@@ -118,6 +121,11 @@
118
121
  </div>
119
122
  {@render rightSection?.()}
120
123
  {/if}
124
+ {#if iconSection}
125
+ <div class="icon-section">
126
+ {@render iconSection()}
127
+ </div>
128
+ {/if}
121
129
  <ThemeSwitcher darkVariant="secondary-subtle" lightVariant="primary-subtle" />
122
130
  {#if isCollapsed}
123
131
  <ActionIcon
@@ -206,4 +214,11 @@
206
214
  .inner-navbar :global(.drawer-btn-right) {
207
215
  margin-left: var(--pui-spacing-2);
208
216
  }
217
+
218
+ .icon-section {
219
+ display: flex;
220
+ align-items: center;
221
+ gap: var(--pui-spacing-1);
222
+ flex-shrink: 0;
223
+ }
209
224
  </style>
@@ -10,6 +10,8 @@ interface Props {
10
10
  inContainer?: boolean;
11
11
  middleSection?: Snippet;
12
12
  rightSection?: Snippet;
13
+ /** Icons displayed to the left of the ThemeSwitcher, visible even when collapsed on mobile */
14
+ iconSection?: Snippet;
13
15
  /** Enable responsive collapse to burger menu on small screens (default: true) */
14
16
  responsive?: boolean;
15
17
  /** Breakpoint in pixels at which the navbar collapses (default: 768) */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@placeholderco/placeholder-ui",
3
- "version": "1.0.10",
3
+ "version": "1.0.11",
4
4
  "description": "A modern, customizable Svelte 5 UI component library with comprehensive theming support",
5
5
  "license": "MIT",
6
6
  "repository": {