ds-one 0.2.5-alpha.15 → 0.2.5-alpha.17

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,6 +1,8 @@
1
- /* version 0.2.5-alpha.15 */
1
+ /* version 0.2.5-alpha.17 */
2
2
 
3
3
  @import url("https://fonts.googleapis.com/css2?family=Noto+Sans+JP:wght@200");
4
+ @import url("https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@800");
5
+ @import url("https://fonts.googleapis.com/css2?family=Noto+Sans+TC:wght@800");
4
6
 
5
7
  @font-face {
6
8
  font-family: GT-America-Standard-Regular;
@@ -26,11 +28,12 @@ input {
26
28
 
27
29
  /* Base/[color] */
28
30
 
29
- --black: #2a2a2a;
30
31
  --white: rgb(255 255 255);
32
+ --light-grey: #e8e8e8;
31
33
  --slate: #1e1e1e;
32
34
  --slate-light: #e6e6e6;
33
35
  --slate-dark: #3c3c3c;
36
+ --black: #2a2a2a;
34
37
 
35
38
  /* Accent/[color] */
36
39
  --tuned-red: #ff5f5f;
@@ -61,6 +64,9 @@ input {
61
64
  /* language specific typefaces */
62
65
 
63
66
  --typeface-regular-jp: "Noto Sans JP";
67
+ --typeface-regular-zh-hans: "Noto Sans SC";
68
+ --typeface-regular-zh-hant: "Noto Sans TC";
69
+ --typeface-regular-zh: var(--typeface-regular-zh-hant);
64
70
 
65
71
  /* typefaces sizes and weight */
66
72
 
@@ -55,7 +55,6 @@ export class Cycle extends LitElement {
55
55
  return {
56
56
  type: { type: String },
57
57
  values: { type: Array },
58
- label: { type: String },
59
58
  currentValue: { type: String, state: true }, // Make this a private state property
60
59
  translationsReady: { type: Boolean, state: true }, // Track if translations are loaded
61
60
  disabled: { type: Boolean, state: true },
@@ -64,15 +63,24 @@ export class Cycle extends LitElement {
64
63
  }
65
64
 
66
65
  static styles = css`
67
- .cycle-container {
68
- display: flex;
69
- justify-content: space-between;
66
+ :host {
67
+ display: inline-flex;
68
+ align-items: center;
69
+ }
70
+
71
+ .cycle {
72
+ display: inline-flex;
73
+ align-items: center;
70
74
  gap: var(--025);
71
- width: 100%;
72
75
  }
73
76
 
74
- .cycle-label {
75
- color: var(--text-color-primary);
77
+ .color-preview {
78
+ width: var(--05);
79
+ height: var(--05);
80
+ border-radius: 999px;
81
+ border: 1px solid
82
+ color-mix(in srgb, var(--text-color-primary) 20%, transparent);
83
+ flex: 0 0 auto;
76
84
  }
77
85
  `;
78
86
 
@@ -80,7 +88,6 @@ export class Cycle extends LitElement {
80
88
  // These are just for TypeScript and don't create shadowing fields
81
89
  declare type: string;
82
90
  declare values: string[];
83
- declare label: string;
84
91
  declare currentValue: string;
85
92
  declare translationsReady: boolean;
86
93
  declare disabled: boolean;
@@ -102,7 +109,6 @@ export class Cycle extends LitElement {
102
109
  // Initialize properties with default values
103
110
  this.type = "";
104
111
  this.values = [];
105
- this.label = "";
106
112
  this.currentValue = "";
107
113
  this.translationsReady = false;
108
114
  this.disabled = false;
@@ -154,9 +160,6 @@ export class Cycle extends LitElement {
154
160
  const availableLanguages = getAvailableLanguagesSync();
155
161
  this.values = availableLanguages;
156
162
  this.currentValue = currentLanguage.value;
157
-
158
- // Set label
159
- this.label = this.getLabel();
160
163
  } else if (this.type === "theme") {
161
164
  // Set up theme cycling
162
165
  this.values = ["light", "dark"];
@@ -164,9 +167,6 @@ export class Cycle extends LitElement {
164
167
  // Set initial value based on current theme
165
168
  const currentThemeValue = currentTheme.get();
166
169
  this.currentValue = currentThemeValue;
167
-
168
- // Set label
169
- this.label = this.getLabel();
170
170
  } else if (this.type === "accent-color") {
171
171
  // Set up accent color cycling
172
172
  this.values = [
@@ -197,9 +197,6 @@ export class Cycle extends LitElement {
197
197
  // Check if this should be disabled based on note behavior
198
198
  const currentPageStyle = getPageStyle();
199
199
  this.disabled = currentPageStyle === "note";
200
-
201
- // Set label
202
- this.label = this.getLabel();
203
200
  } else if (this.type === "page-style") {
204
201
  // Set up page style cycling
205
202
  this.values = ["note", "page"];
@@ -207,18 +204,12 @@ export class Cycle extends LitElement {
207
204
  // Set initial value based on current page style
208
205
  const currentPageStyle = getPageStyle();
209
206
  this.currentValue = currentPageStyle;
210
-
211
- // Set label
212
- this.label = this.getLabel();
213
207
  } else if (this.type === "icon-only") {
214
208
  // Set up icon-only cycling (no label)
215
209
  this.values = ["note", "page"];
216
210
 
217
211
  // Set initial value
218
212
  this.currentValue = this.values[0];
219
-
220
- // No label for icon-only type
221
- this.label = "";
222
213
  }
223
214
 
224
215
  // Request update to re-render with new values
@@ -252,16 +243,10 @@ export class Cycle extends LitElement {
252
243
  // Get current language
253
244
  const currentLang = currentLanguage.value;
254
245
  this.currentValue = currentLang;
255
-
256
- // Update label
257
- this.label = this.getLabel();
258
246
  } else if (this.type === "theme") {
259
247
  // Get current theme
260
248
  const currentThemeValue = currentTheme.get();
261
249
  this.currentValue = currentThemeValue;
262
-
263
- // Update label
264
- this.label = this.getLabel();
265
250
  } else if (this.type === "accent-color") {
266
251
  // Get current accent color
267
252
  const currentAccentColor = getAccentColor();
@@ -277,23 +262,14 @@ export class Cycle extends LitElement {
277
262
  // Check if this should be disabled based on note behavior
278
263
  const currentPageStyle = getPageStyle();
279
264
  this.disabled = currentPageStyle === "note";
280
-
281
- // Update label
282
- this.label = this.getLabel();
283
265
  } else if (this.type === "page-style") {
284
266
  // Get current page style
285
267
  const currentPageStyle = getPageStyle();
286
268
  this.currentValue = currentPageStyle;
287
-
288
- // Update label
289
- this.label = this.getLabel();
290
269
  } else if (this.type === "icon-only") {
291
270
  // Get current page style for icon-only
292
271
  const currentPageStyle = getPageStyle();
293
272
  this.currentValue = currentPageStyle;
294
-
295
- // Update label
296
- this.label = "";
297
273
  }
298
274
 
299
275
  this.requestUpdate();
@@ -463,9 +439,6 @@ export class Cycle extends LitElement {
463
439
  // Save preferences
464
440
  savePreferences({ pageStyle: newIconOnlyValue });
465
441
 
466
- // No label update for icon-only type
467
- this.label = "";
468
-
469
442
  // Dispatch page style change event
470
443
  window.dispatchEvent(
471
444
  new CustomEvent("page-style-changed", {
@@ -474,9 +447,6 @@ export class Cycle extends LitElement {
474
447
  );
475
448
  }
476
449
 
477
- // Update label
478
- this.label = this.getLabel();
479
-
480
450
  // Request update to re-render
481
451
  this.requestUpdate();
482
452
  }
@@ -584,146 +554,54 @@ export class Cycle extends LitElement {
584
554
  return html`<span>${style}</span>`;
585
555
  }
586
556
 
587
- getLabel(): string {
588
- if (this.type === "language") {
589
- // Try to get translated label
590
- if (this.translationsReady) {
591
- const translatedLabel = translate("language");
592
- if (translatedLabel && translatedLabel !== "language") {
593
- return translatedLabel;
594
- }
595
- }
596
-
597
- // Fall back to English
598
- return "Language";
599
- } else if (this.type === "theme") {
600
- // Try to get translated label
601
- if (this.translationsReady) {
602
- const translatedLabel = translate("theme");
603
- if (translatedLabel && translatedLabel !== "theme") {
604
- return translatedLabel;
605
- }
606
- }
607
-
608
- // Fall back to English
609
- return "Theme";
610
- } else if (this.type === "accent-color") {
611
- // Try to get translated label
612
- if (this.translationsReady) {
613
- const translatedLabel = translate("accentColor");
614
- if (translatedLabel && translatedLabel !== "accentColor") {
615
- return translatedLabel;
616
- }
617
- }
618
-
619
- // Fall back to English
620
- return "Accent Color";
621
- } else if (this.type === "notes-style-medium") {
622
- // Try to get translated label
623
- if (this.translationsReady) {
624
- const translatedLabel = translate("notesStyle");
625
- if (translatedLabel && translatedLabel !== "notesStyle") {
626
- return translatedLabel;
627
- }
628
- }
629
-
630
- // Fall back to English
631
- return "Notes Style";
632
- } else if (this.type === "page-style") {
633
- // Try to get translated label
634
- if (this.translationsReady) {
635
- const translatedLabel = translate("clickingItem");
636
- if (translatedLabel && translatedLabel !== "clickingItem") {
637
- return translatedLabel;
638
- }
639
- }
640
-
641
- // Fall back to English
642
- return "Clic";
643
- } else if (this.type === "icon-only") {
644
- // No label for icon-only type
645
- return "";
646
- }
647
-
648
- return this.label;
649
- }
650
-
651
557
  render() {
652
558
  return html`
653
- <div class="cycle-container">
654
- ${this.type !== "icon-only"
655
- ? html`${this.type === "language"
559
+ <div class="cycle">
560
+ <ds-button
561
+ variant=${this.variant ||
562
+ (this.type === "language" || this.type === "theme"
563
+ ? "secondary"
564
+ : "primary")}
565
+ ?disabled=${this.disabled}
566
+ @click=${this.handleButtonClick}
567
+ >
568
+ ${this.type === "notes-style-medium" || this.type === "icon-only"
569
+ ? html`<span
570
+ style="display: inline-flex; align-items: center; gap: var(--025)"
571
+ >${this.getValueDisplay(this.currentValue)}</span
572
+ >`
573
+ : this.type === "language"
656
574
  ? html`<ds-text
657
- key="language"
658
- default-value="Language"
659
- class="cycle-label"
575
+ default-value=${this.getValueDisplay(this.currentValue)}
660
576
  ></ds-text>`
661
577
  : this.type === "theme"
662
578
  ? html`<ds-text
663
- key="theme"
664
- default-value="Theme"
665
- class="cycle-label"
579
+ key=${this.currentValue}
580
+ default-value=${this.currentValue}
666
581
  ></ds-text>`
667
582
  : this.type === "accent-color"
668
583
  ? html`<ds-text
669
- key="accentColor"
670
- default-value="Accent color"
671
- class="cycle-label"
584
+ key=${this.getColorKey(this.currentValue)}
585
+ default-value=${this.getColorName(this.currentValue)}
672
586
  ></ds-text>`
673
- : html`<span class="cycle-label">${this.label}</span>`}`
674
- : ""}
675
- <div
676
- style="display: flex; align-items: center; ${this.type === "icon-only"
677
- ? "justify-content: center;"
678
- : ""}"
679
- >
680
- <ds-button
681
- variant=${this.variant ||
682
- (this.type === "language" || this.type === "theme"
683
- ? "secondary"
684
- : "primary")}
685
- ?disabled=${this.disabled}
686
- @click=${this.handleButtonClick}
687
- >
688
- ${this.type === "notes-style-medium" || this.type === "icon-only"
689
- ? html`<span
690
- style="display: inline-flex; align-items: center; gap: var(--025)"
691
- >${this.getValueDisplay(this.currentValue)}</span
692
- >`
693
- : this.type === "language"
694
- ? html`<ds-text
695
- default-value=${this.getValueDisplay(this.currentValue)}
696
- ></ds-text>`
697
- : this.type === "theme"
698
- ? html`<ds-text
699
- key=${this.currentValue}
700
- default-value=${this.currentValue}
701
- ></ds-text>`
702
- : this.type === "accent-color"
587
+ : this.type === "page-style"
703
588
  ? html`<ds-text
704
- key=${this.getColorKey(this.currentValue)}
705
- default-value=${this.getColorName(this.currentValue)}
589
+ key=${this.currentValue}
590
+ default-value=${this.currentValue}
706
591
  ></ds-text>`
707
- : this.type === "page-style"
708
- ? html`<ds-text
709
- key=${this.currentValue}
710
- default-value=${this.currentValue}
711
- ></ds-text>`
712
- : html`<ds-text
713
- default-value=${this.getValueDisplay(
714
- this.currentValue
715
- )}
716
- ></ds-text>`}
717
- </ds-button>
718
- ${this.type === "accent-color"
719
- ? html`
720
- <div
721
- class="color-preview"
722
- style="background-color: var(${this.currentValue})"
723
- ></div>
724
- `
725
- : ""}
726
- </div>
592
+ : html`<ds-text
593
+ default-value=${this.getValueDisplay(this.currentValue)}
594
+ ></ds-text>`}
595
+ </ds-button>
596
+
597
+ ${this.type === "accent-color"
598
+ ? html`
599
+ <div
600
+ class="color-preview"
601
+ style="background-color: var(${this.currentValue})"
602
+ ></div>
603
+ `
604
+ : ""}
727
605
  </div>
728
606
  `;
729
607
  }
@@ -0,0 +1,110 @@
1
+ import { LitElement, html, css } from "lit";
2
+
3
+ /**
4
+ * Full-width vertical spacer.
5
+ *
6
+ * Usage:
7
+ * - <ds-gap unit></ds-gap>
8
+ * - <ds-gap double></ds-gap>
9
+ * - <ds-gap size="05"></ds-gap>
10
+ */
11
+ export class Gap extends LitElement {
12
+ static properties = {
13
+ /** Raw scale token selector ("01", "025", "05", "08", "1", "2", "3", "4", "8", "12") */
14
+ size: { type: String, reflect: true },
15
+ };
16
+
17
+ declare size: string;
18
+
19
+ constructor() {
20
+ super();
21
+ this.size = "";
22
+ }
23
+
24
+ static styles = css`
25
+ :host {
26
+ display: block;
27
+ width: 100%;
28
+ /* Default if no attribute is provided */
29
+ --gap-size: var(--unit);
30
+ height: var(--gap-size);
31
+ flex: 0 0 auto;
32
+ }
33
+
34
+ /* Semantic sizing tokens (from DS1/1-root/one.css) */
35
+ :host([tenth]) {
36
+ --gap-size: var(--tenth);
37
+ }
38
+ :host([quarter]) {
39
+ --gap-size: var(--quarter);
40
+ }
41
+ :host([half]) {
42
+ --gap-size: var(--half);
43
+ }
44
+ :host([eight-tenth]) {
45
+ --gap-size: var(--eight-tenth);
46
+ }
47
+ :host([unit]) {
48
+ --gap-size: var(--unit);
49
+ }
50
+ :host([double]) {
51
+ --gap-size: var(--double);
52
+ }
53
+ :host([triple]) {
54
+ --gap-size: var(--triple);
55
+ }
56
+ :host([quad]) {
57
+ --gap-size: var(--quad);
58
+ }
59
+ :host([oct]) {
60
+ --gap-size: var(--oct);
61
+ }
62
+ :host([dozen]) {
63
+ --gap-size: var(--dozen);
64
+ }
65
+
66
+ /* Raw scale sizing (size="...") */
67
+ :host([size="01"]) {
68
+ --gap-size: var(--01);
69
+ }
70
+ :host([size="025"]) {
71
+ --gap-size: var(--025);
72
+ }
73
+ :host([size="05"]) {
74
+ --gap-size: var(--05);
75
+ }
76
+ :host([size="08"]) {
77
+ --gap-size: var(--08);
78
+ }
79
+ :host([size="1"]) {
80
+ --gap-size: var(--1);
81
+ }
82
+ :host([size="2"]) {
83
+ --gap-size: var(--2);
84
+ }
85
+ :host([size="3"]) {
86
+ --gap-size: var(--3);
87
+ }
88
+ :host([size="4"]) {
89
+ --gap-size: var(--4);
90
+ }
91
+ :host([size="8"]) {
92
+ --gap-size: var(--8);
93
+ }
94
+ :host([size="12"]) {
95
+ --gap-size: var(--12);
96
+ }
97
+ `;
98
+
99
+ render() {
100
+ return html``;
101
+ }
102
+ }
103
+
104
+ customElements.define("ds-gap", Gap);
105
+
106
+ declare global {
107
+ interface HTMLElementTagNameMap {
108
+ "ds-gap": Gap;
109
+ }
110
+ }
@@ -62,6 +62,17 @@ export class Text extends LitElement {
62
62
  :host([data-language="ja"]) {
63
63
  font-family: var(--typeface-regular-jp);
64
64
  }
65
+
66
+ :host([data-language="zh"]),
67
+ :host([data-language="zh-hant"]) {
68
+ font-family: var(--typeface-regular-zh-hant);
69
+ font-weight: 800;
70
+ }
71
+
72
+ :host([data-language="zh-hans"]) {
73
+ font-family: var(--typeface-regular-zh-hans);
74
+ font-weight: 800;
75
+ }
65
76
  `;
66
77
 
67
78
  connectedCallback() {
@@ -108,13 +119,32 @@ export class Text extends LitElement {
108
119
 
109
120
  _updateLanguageAttribute() {
110
121
  const lang = this._currentLanguage || currentLanguage.value;
111
- // Check if language is Japanese (handles "ja", "ja-JP", etc.)
112
- const primaryLang = lang?.toLowerCase().split(/[-_]/)[0] || "";
122
+ // Handles "ja", "ja-JP", "zh-Hant", "zh-Hans", etc.
123
+ const parts = (lang || "").toLowerCase().split(/[-_]/).filter(Boolean);
124
+ const primaryLang = parts[0] || "";
125
+
113
126
  if (primaryLang === "ja") {
114
127
  this.setAttribute("data-language", "ja");
115
- } else {
116
- this.removeAttribute("data-language");
128
+ return;
117
129
  }
130
+
131
+ if (primaryLang === "zh") {
132
+ // Prefer explicit script; otherwise infer from common regions.
133
+ const hasHans =
134
+ parts.includes("hans") || parts.includes("cn") || parts.includes("sg");
135
+ const hasHant =
136
+ parts.includes("hant") ||
137
+ parts.includes("tw") ||
138
+ parts.includes("hk") ||
139
+ parts.includes("mo");
140
+
141
+ if (hasHans) this.setAttribute("data-language", "zh-hans");
142
+ else if (hasHant) this.setAttribute("data-language", "zh-hant");
143
+ else this.setAttribute("data-language", "zh");
144
+ return;
145
+ }
146
+
147
+ this.removeAttribute("data-language");
118
148
  }
119
149
 
120
150
  _loadText() {
@@ -0,0 +1,112 @@
1
+ import { LitElement, html, css } from "lit";
2
+ import "../2-core/ds-text";
3
+ import "../2-core/ds-icon";
4
+ import "./ds-row";
5
+
6
+ /**
7
+ * Native accordion using <details>/<summary> (no JS toggle logic).
8
+ *
9
+ * Usage:
10
+ * <ds-accordion summary-key="howItBegan" details-key="designedInHokkaido"></ds-accordion>
11
+ */
12
+ export class Accordion extends LitElement {
13
+ static properties = {
14
+ summaryKey: { type: String, attribute: "summary-key" },
15
+ detailsKey: { type: String, attribute: "details-key" },
16
+ open: { type: Boolean, reflect: true },
17
+ };
18
+
19
+ declare summaryKey: string;
20
+ declare detailsKey: string;
21
+ declare open: boolean;
22
+
23
+ constructor() {
24
+ super();
25
+ this.summaryKey = "";
26
+ this.detailsKey = "";
27
+ this.open = false;
28
+ }
29
+
30
+ static styles = css`
31
+ :host {
32
+ display: block;
33
+ width: calc(240px * var(--sf));
34
+ color: var(--text-color-primary);
35
+ }
36
+
37
+ details {
38
+ width: 100%;
39
+ }
40
+
41
+ summary {
42
+ cursor: pointer;
43
+ user-select: none;
44
+ list-style: none;
45
+ outline: none;
46
+ }
47
+
48
+ summary::-webkit-details-marker {
49
+ display: none;
50
+ }
51
+
52
+ .summaryRow {
53
+ width: 100%;
54
+ }
55
+
56
+ ds-icon.chevron {
57
+ transform: rotate(0deg);
58
+ transition: transform 140ms ease;
59
+ }
60
+
61
+ details[open] ds-icon.chevron {
62
+ transform: rotate(180deg);
63
+ }
64
+
65
+ .detailsBody {
66
+ padding-top: calc(var(--half) * var(--sf));
67
+ }
68
+
69
+ .detailsText {
70
+ display: block;
71
+ white-space: normal;
72
+ text-align: left;
73
+ }
74
+ `;
75
+
76
+ render() {
77
+ return html`
78
+ <details ?open=${this.open}>
79
+ <summary>
80
+ <ds-row class="summaryRow" type="centered">
81
+ <ds-text .key=${this.summaryKey}></ds-text>
82
+ <ds-icon class="chevron" aria-hidden="true">
83
+ <svg
84
+ viewBox="0 0 10.157 8.219"
85
+ xmlns="http://www.w3.org/2000/svg"
86
+ aria-hidden="true"
87
+ focusable="false"
88
+ >
89
+ <path
90
+ d="M5.078 8.219L0 3.141L1.414 1.727L5.078 5.391L8.743 1.727L10.157 3.141L5.078 8.219Z"
91
+ fill="currentColor"
92
+ />
93
+ </svg>
94
+ </ds-icon>
95
+ </ds-row>
96
+ </summary>
97
+
98
+ <div class="detailsBody">
99
+ <ds-text class="detailsText" .key=${this.detailsKey}></ds-text>
100
+ </div>
101
+ </details>
102
+ `;
103
+ }
104
+ }
105
+
106
+ customElements.define("ds-accordion", Accordion);
107
+
108
+ declare global {
109
+ interface HTMLElementTagNameMap {
110
+ "ds-accordion": Accordion;
111
+ }
112
+ }
@@ -102,13 +102,14 @@ export class Layout extends LitElement {
102
102
  :host([mode="app"]) {
103
103
  --app-cols: 100%;
104
104
  --app-rows: calc(var(--unit) * var(--sf)) calc(var(--unit) * var(--sf))
105
- calc(var(--unit) * var(--sf)) calc(var(--dozen) * var(--sf))
106
- calc(var(--quad) * var(--sf)) calc(var(--unit) * var(--sf));
105
+ calc(var(--unit) * var(--sf)) calc(var(--double) * var(--sf))
106
+ calc(var(--dozen) * var(--sf)) calc(var(--quad) * var(--sf))
107
+ calc(var(--unit) * var(--sf));
107
108
  --app-areas: "banner" "." "header" "." "main" "." "footer";
108
109
  --app-overlay-cols: 100%;
109
110
  --app-overlay-rows: calc(var(--unit) * var(--sf))
110
111
  calc(var(--unit) * var(--sf)) calc(var(--unit) * var(--sf))
111
- calc(var(--unit) * var(--sf)) calc(var(--dozen) * var(--sf))
112
+ calc(var(--double) * var(--sf)) calc(var(--dozen) * var(--sf))
112
113
  calc(var(--quad) * var(--sf)) calc(var(--unit) * var(--sf));
113
114
  --app-overlay-areas: "banner" "." "header" "." "main" "." "footer";
114
115
  grid-template-columns: var(--app-cols);
package/DS1/index.ts CHANGED
@@ -31,6 +31,7 @@ export * from "./0-face/theme";
31
31
 
32
32
  export * from "./2-core/ds-button";
33
33
  export * from "./2-core/ds-cycle";
34
+ export * from "./2-core/ds-gap";
34
35
  export * from "./2-core/ds-icon";
35
36
  export * from "./2-core/ds-text";
36
37
  export * from "./2-core/ds-tooltip";
@@ -41,6 +42,7 @@ export * from "./2-core/ds-date";
41
42
  // ============================================================================
42
43
 
43
44
  export * from "./3-unit/ds-list";
45
+ export * from "./3-unit/ds-accordion";
44
46
  export * from "./3-unit/ds-row";
45
47
  export * from "./3-unit/ds-table";
46
48