@waggylabs/yumekit 0.4.1-beta.71 → 0.4.1-beta.72

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.
@@ -4,6 +4,7 @@ export class YumeDate extends HTMLElement {
4
4
  _internals: ElementInternals;
5
5
  _onDocumentClick(e: any): void;
6
6
  _suppressBlurApply: boolean;
7
+ _selectedParts: Set<any>;
7
8
  connectedCallback(): void;
8
9
  disconnectedCallback(): void;
9
10
  attributeChangedCallback(name: any, oldVal: any, newVal: any): void;
@@ -1,9 +1,8 @@
1
1
  declare namespace _default {
2
- export let title: string;
3
- export let tags: string[];
4
- export { docsParams as parameters };
5
- export let decorators: ((story: any) => string)[];
6
- export namespace argTypes {
2
+ let title: string;
3
+ let tags: string[];
4
+ let decorators: ((story: any) => string)[];
5
+ namespace argTypes {
7
6
  namespace mode {
8
7
  let control: string;
9
8
  let options: string[];
@@ -142,8 +141,22 @@ declare namespace _default {
142
141
  }
143
142
  export { table_8 as table };
144
143
  }
144
+ namespace showSeconds {
145
+ let control_11: string;
146
+ export { control_11 as control };
147
+ let description_11: string;
148
+ export { description_11 as description };
149
+ export namespace table_9 {
150
+ export namespace defaultValue_9 {
151
+ let summary_9: string;
152
+ export { summary_9 as summary };
153
+ }
154
+ export { defaultValue_9 as defaultValue };
155
+ }
156
+ export { table_9 as table };
157
+ }
145
158
  }
146
- export namespace args {
159
+ namespace args {
147
160
  let mode_1: string;
148
161
  export { mode_1 as mode };
149
162
  let size_1: string;
@@ -164,8 +177,10 @@ declare namespace _default {
164
177
  export { showTime_1 as showTime };
165
178
  let showMinutes_1: boolean;
166
179
  export { showMinutes_1 as showMinutes };
180
+ let showSeconds_1: boolean;
181
+ export { showSeconds_1 as showSeconds };
167
182
  }
168
- export function render(args: any): string;
183
+ function render(args: any): string;
169
184
  }
170
185
  export default _default;
171
186
  /** Default single-date input. */
@@ -231,13 +246,3 @@ export namespace Invalid {
231
246
  }
232
247
  export { args_7 as args };
233
248
  }
234
- /** Interactive playground. */
235
- export const Playground: {};
236
- declare namespace docsParams {
237
- namespace docs {
238
- namespace story {
239
- let inline: boolean;
240
- let height: string;
241
- }
242
- }
243
- }
@@ -1116,8 +1116,10 @@ class YumeSelect extends HTMLElement {
1116
1116
  }
1117
1117
 
1118
1118
  .dropdown {
1119
- position: fixed;
1119
+ position: absolute;
1120
1120
  z-index: var(--component-select-z-index, 6000);
1121
+ left: 0;
1122
+ right: 0;
1121
1123
  background: var(--component-select-background);
1122
1124
  border: var(--component-inputs-border-width) solid var(--component-select-border-color);
1123
1125
  border-radius: var(--component-inputs-border-radius-outer);
@@ -1506,18 +1508,14 @@ class YumeSelect extends HTMLElement {
1506
1508
  _positionDropdown() {
1507
1509
  const rect = this.selectContainer.getBoundingClientRect();
1508
1510
  const gap = 4;
1509
-
1510
- this.dropdown.style.left = `${rect.left}px`;
1511
- this.dropdown.style.width = `${rect.width}px`;
1512
-
1513
- const spaceBelow = window.innerHeight - rect.bottom - gap;
1514
1511
  const maxH = 200;
1512
+ const spaceBelow = window.innerHeight - rect.bottom - gap;
1515
1513
 
1516
1514
  if (spaceBelow >= maxH || spaceBelow >= rect.top) {
1517
- this.dropdown.style.top = `${rect.bottom + gap}px`;
1515
+ this.dropdown.style.top = `${this.selectContainer.offsetHeight + gap}px`;
1518
1516
  this.dropdown.style.bottom = "auto";
1519
1517
  } else {
1520
- this.dropdown.style.bottom = `${window.innerHeight - rect.top + gap}px`;
1518
+ this.dropdown.style.bottom = `${this.selectContainer.offsetHeight + gap}px`;
1521
1519
  this.dropdown.style.top = "auto";
1522
1520
  }
1523
1521
  }
@@ -1930,7 +1928,9 @@ class YumeDatepicker extends HTMLElement {
1930
1928
  // Apply the year delta relative to what the right panel currently shows
1931
1929
  const rightVd = this._viewDateForSide("right");
1932
1930
  const yearDiff = targetYear - rightVd.getFullYear();
1933
- this._viewDate.setFullYear(this._viewDate.getFullYear() + yearDiff);
1931
+ this._viewDate.setFullYear(
1932
+ this._viewDate.getFullYear() + yearDiff,
1933
+ );
1934
1934
  } else {
1935
1935
  this._viewDate.setFullYear(targetYear);
1936
1936
  }
@@ -1971,7 +1971,7 @@ class YumeDatepicker extends HTMLElement {
1971
1971
  if (side === "right") this._endTime.h = h;
1972
1972
  else this._startTime.h = h;
1973
1973
  this._applyTimesToDates();
1974
- this._emitChange();
1974
+ this._emitChange("hour");
1975
1975
  this.render();
1976
1976
  });
1977
1977
  });
@@ -1983,7 +1983,7 @@ class YumeDatepicker extends HTMLElement {
1983
1983
  if (side === "right") this._endTime.m = m;
1984
1984
  else this._startTime.m = m;
1985
1985
  this._applyTimesToDates();
1986
- this._emitChange();
1986
+ this._emitChange("minute");
1987
1987
  this.render();
1988
1988
  });
1989
1989
  });
@@ -1995,7 +1995,7 @@ class YumeDatepicker extends HTMLElement {
1995
1995
  if (side === "right") this._endTime.s = s;
1996
1996
  else this._startTime.s = s;
1997
1997
  this._applyTimesToDates();
1998
- this._emitChange();
1998
+ this._emitChange("second");
1999
1999
  this.render();
2000
2000
  });
2001
2001
  });
@@ -2055,6 +2055,26 @@ class YumeDatepicker extends HTMLElement {
2055
2055
  _buildHeader(vd, side, isRange) {
2056
2056
  const year = vd.getFullYear();
2057
2057
  const month = vd.getMonth();
2058
+
2059
+ // Month and year picker modes: simple label, no selects or nav
2060
+ if (!this.showDays) {
2061
+ let label;
2062
+ if (this.showMonths) {
2063
+ label = String(year);
2064
+ } else {
2065
+ const minY = this._minDate()?.getFullYear() ?? year - 10;
2066
+ const maxY = this._maxDate()?.getFullYear() ?? year + 10;
2067
+ label = `${minY} – ${maxY}`;
2068
+ }
2069
+ return `
2070
+ <div class="cal-header">
2071
+ <div class="header-selects">
2072
+ <span class="header-label">${label}</span>
2073
+ </div>
2074
+ </div>
2075
+ `;
2076
+ }
2077
+
2058
2078
  const showPrev = !isRange || side === "left";
2059
2079
  const showNext = !isRange || side === "right";
2060
2080
 
@@ -2194,6 +2214,11 @@ class YumeDatepicker extends HTMLElement {
2194
2214
  .month-sel { min-width: 120px; }
2195
2215
  .year-sel { min-width: 80px; }
2196
2216
 
2217
+ .header-label {
2218
+ font-weight: 600;
2219
+ white-space: nowrap;
2220
+ }
2221
+
2197
2222
  /* ---- Day grid ---- */
2198
2223
 
2199
2224
  .day-grid {
@@ -2400,7 +2425,7 @@ class YumeDatepicker extends HTMLElement {
2400
2425
  `;
2401
2426
  }
2402
2427
 
2403
- _emitChange() {
2428
+ _emitChange(source) {
2404
2429
  this._suppressParse = true;
2405
2430
  const value = this._buildValueString();
2406
2431
  if (value !== this.getAttribute("value")) {
@@ -2413,6 +2438,7 @@ class YumeDatepicker extends HTMLElement {
2413
2438
  composed: true,
2414
2439
  detail: {
2415
2440
  value,
2441
+ source,
2416
2442
  startDate: this._startDate
2417
2443
  ? new Date(this._startDate)
2418
2444
  : null,
@@ -2463,7 +2489,7 @@ class YumeDatepicker extends HTMLElement {
2463
2489
  this._startDate = date;
2464
2490
  }
2465
2491
  this._applyTimesToDates();
2466
- this._emitChange();
2492
+ this._emitChange("day");
2467
2493
  this.render();
2468
2494
  }
2469
2495
 
@@ -2620,6 +2646,7 @@ class YumeDate extends HTMLElement {
2620
2646
  this.attachShadow({ mode: "open" });
2621
2647
  this._onDocumentClick = this._onDocumentClick.bind(this);
2622
2648
  this._suppressBlurApply = false;
2649
+ this._selectedParts = new Set();
2623
2650
  }
2624
2651
 
2625
2652
  connectedCallback() {
@@ -3034,7 +3061,9 @@ class YumeDate extends HTMLElement {
3034
3061
  });
3035
3062
 
3036
3063
  // Picker date selection
3064
+ // Guard: ignore composed change events from child y-selects (month/year dropdowns)
3037
3065
  picker.addEventListener("change", (e) => {
3066
+ if (e.composedPath()[0] !== picker) return;
3038
3067
  this._suppressBlurApply = true;
3039
3068
  const { value, formatted } = e.detail;
3040
3069
  this.setAttribute("value", value);
@@ -3044,7 +3073,18 @@ class YumeDate extends HTMLElement {
3044
3073
 
3045
3074
  this._updateClearBtn();
3046
3075
 
3047
- if (this.mode === "single" && value) this._setOpen(false);
3076
+ // Auto-close once all available parts have been selected
3077
+ if (this.mode === "single" && value) {
3078
+ const src = e.detail.source;
3079
+ if (src) this._selectedParts.add(src);
3080
+ const required = ["day"];
3081
+ if (picker.showTime) required.push("hour");
3082
+ if (picker.showMinutes) required.push("minute");
3083
+ if (picker.showSeconds) required.push("second");
3084
+ if (required.every((p) => this._selectedParts.has(p))) {
3085
+ this._setOpen(false);
3086
+ }
3087
+ }
3048
3088
 
3049
3089
  this.dispatchEvent(
3050
3090
  new CustomEvent("change", {
@@ -3229,6 +3269,7 @@ class YumeDate extends HTMLElement {
3229
3269
  if (!popup || !trigger) return;
3230
3270
  popup.hidden = !open;
3231
3271
  trigger.setAttribute("aria-expanded", String(open));
3272
+ if (open) this._selectedParts.clear();
3232
3273
  }
3233
3274
 
3234
3275
  _syncPickerValue() {
@@ -3286,15 +3327,15 @@ class YumeDate extends HTMLElement {
3286
3327
  const fmt = this.format;
3287
3328
 
3288
3329
  const tokens = [
3289
- { token: "YYYY", key: "year", re: "(\\d{4})" },
3290
- { token: "MM", key: "month", re: "(\\d{1,2})" },
3291
- { token: "DD", key: "day", re: "(\\d{1,2})" },
3292
- { token: "HH", key: "hour24", re: "(\\d{1,2})" },
3293
- { token: "hh", key: "hour12", re: "(\\d{1,2})" },
3294
- { token: "mm", key: "minute", re: "(\\d{1,2})" },
3295
- { token: "ss", key: "second", re: "(\\d{1,2})" },
3296
- { token: "A", key: "ampm", re: "(AM|PM)" },
3297
- { token: "a", key: "ampm", re: "(am|pm)" },
3330
+ { token: "YYYY", key: "year", re: "(\\d{4})" },
3331
+ { token: "MM", key: "month", re: "(\\d{1,2})" },
3332
+ { token: "DD", key: "day", re: "(\\d{1,2})" },
3333
+ { token: "HH", key: "hour24", re: "(\\d{1,2})" },
3334
+ { token: "hh", key: "hour12", re: "(\\d{1,2})" },
3335
+ { token: "mm", key: "minute", re: "(\\d{1,2})" },
3336
+ { token: "ss", key: "second", re: "(\\d{1,2})" },
3337
+ { token: "A", key: "ampm", re: "(AM|PM)" },
3338
+ { token: "a", key: "ampm", re: "(am|pm)" },
3298
3339
  ];
3299
3340
 
3300
3341
  // Replace each token with a placeholder, then escape literal chars,
@@ -3316,11 +3357,15 @@ class YumeDate extends HTMLElement {
3316
3357
  if (!match) return null;
3317
3358
 
3318
3359
  const parts = {};
3319
- order.forEach((t, i) => { parts[t.key] = match[i + 1]; });
3360
+ order.forEach((t, i) => {
3361
+ parts[t.key] = match[i + 1];
3362
+ });
3320
3363
 
3321
- const year = parts.year ? parseInt(parts.year) : new Date().getFullYear();
3322
- const month = parts.month ? parseInt(parts.month) - 1 : 0;
3323
- const day = parts.day ? parseInt(parts.day) : 1;
3364
+ const year = parts.year
3365
+ ? parseInt(parts.year)
3366
+ : new Date().getFullYear();
3367
+ const month = parts.month ? parseInt(parts.month) - 1 : 0;
3368
+ const day = parts.day ? parseInt(parts.day) : 1;
3324
3369
 
3325
3370
  let hour = 0;
3326
3371
  if (parts.hour24 !== undefined) {
@@ -72,7 +72,7 @@ export class YumeDatepicker extends HTMLElement {
72
72
  _buildTimeColumn(side: any): string;
73
73
  _buildValueString(): any;
74
74
  _buildYearGrid(vd: any): string;
75
- _emitChange(): void;
75
+ _emitChange(source: any): void;
76
76
  _suppressParse: boolean;
77
77
  _formatDate(date: any): string;
78
78
  _handleDayClick(date: any): void;
@@ -1,8 +1,8 @@
1
1
  declare namespace _default {
2
- export let title: string;
3
- export let tags: string[];
4
- export { docsParams as parameters };
5
- export namespace argTypes {
2
+ let title: string;
3
+ let tags: string[];
4
+ let decorators: ((story: any) => string)[];
5
+ namespace argTypes {
6
6
  namespace mode {
7
7
  let control: string;
8
8
  let options: string[];
@@ -146,7 +146,7 @@ declare namespace _default {
146
146
  export { table_8 as table };
147
147
  }
148
148
  }
149
- export namespace args {
149
+ namespace args {
150
150
  let mode_1: string;
151
151
  export { mode_1 as mode };
152
152
  let color_1: string;
@@ -166,7 +166,7 @@ declare namespace _default {
166
166
  let showDays_1: boolean;
167
167
  export { showDays_1 as showDays };
168
168
  }
169
- export function render(args: any): string;
169
+ function render(args: any): string;
170
170
  }
171
171
  export default _default;
172
172
  /** Default single-date picker. */
@@ -266,11 +266,3 @@ export namespace CustomFormat {
266
266
  }
267
267
  /** Interactive playground. */
268
268
  export const Playground: {};
269
- declare namespace docsParams {
270
- namespace docs {
271
- namespace story {
272
- let inline: boolean;
273
- let height: string;
274
- }
275
- }
276
- }
@@ -1116,8 +1116,10 @@ class YumeSelect extends HTMLElement {
1116
1116
  }
1117
1117
 
1118
1118
  .dropdown {
1119
- position: fixed;
1119
+ position: absolute;
1120
1120
  z-index: var(--component-select-z-index, 6000);
1121
+ left: 0;
1122
+ right: 0;
1121
1123
  background: var(--component-select-background);
1122
1124
  border: var(--component-inputs-border-width) solid var(--component-select-border-color);
1123
1125
  border-radius: var(--component-inputs-border-radius-outer);
@@ -1506,18 +1508,14 @@ class YumeSelect extends HTMLElement {
1506
1508
  _positionDropdown() {
1507
1509
  const rect = this.selectContainer.getBoundingClientRect();
1508
1510
  const gap = 4;
1509
-
1510
- this.dropdown.style.left = `${rect.left}px`;
1511
- this.dropdown.style.width = `${rect.width}px`;
1512
-
1513
- const spaceBelow = window.innerHeight - rect.bottom - gap;
1514
1511
  const maxH = 200;
1512
+ const spaceBelow = window.innerHeight - rect.bottom - gap;
1515
1513
 
1516
1514
  if (spaceBelow >= maxH || spaceBelow >= rect.top) {
1517
- this.dropdown.style.top = `${rect.bottom + gap}px`;
1515
+ this.dropdown.style.top = `${this.selectContainer.offsetHeight + gap}px`;
1518
1516
  this.dropdown.style.bottom = "auto";
1519
1517
  } else {
1520
- this.dropdown.style.bottom = `${window.innerHeight - rect.top + gap}px`;
1518
+ this.dropdown.style.bottom = `${this.selectContainer.offsetHeight + gap}px`;
1521
1519
  this.dropdown.style.top = "auto";
1522
1520
  }
1523
1521
  }
@@ -1930,7 +1928,9 @@ class YumeDatepicker extends HTMLElement {
1930
1928
  // Apply the year delta relative to what the right panel currently shows
1931
1929
  const rightVd = this._viewDateForSide("right");
1932
1930
  const yearDiff = targetYear - rightVd.getFullYear();
1933
- this._viewDate.setFullYear(this._viewDate.getFullYear() + yearDiff);
1931
+ this._viewDate.setFullYear(
1932
+ this._viewDate.getFullYear() + yearDiff,
1933
+ );
1934
1934
  } else {
1935
1935
  this._viewDate.setFullYear(targetYear);
1936
1936
  }
@@ -1971,7 +1971,7 @@ class YumeDatepicker extends HTMLElement {
1971
1971
  if (side === "right") this._endTime.h = h;
1972
1972
  else this._startTime.h = h;
1973
1973
  this._applyTimesToDates();
1974
- this._emitChange();
1974
+ this._emitChange("hour");
1975
1975
  this.render();
1976
1976
  });
1977
1977
  });
@@ -1983,7 +1983,7 @@ class YumeDatepicker extends HTMLElement {
1983
1983
  if (side === "right") this._endTime.m = m;
1984
1984
  else this._startTime.m = m;
1985
1985
  this._applyTimesToDates();
1986
- this._emitChange();
1986
+ this._emitChange("minute");
1987
1987
  this.render();
1988
1988
  });
1989
1989
  });
@@ -1995,7 +1995,7 @@ class YumeDatepicker extends HTMLElement {
1995
1995
  if (side === "right") this._endTime.s = s;
1996
1996
  else this._startTime.s = s;
1997
1997
  this._applyTimesToDates();
1998
- this._emitChange();
1998
+ this._emitChange("second");
1999
1999
  this.render();
2000
2000
  });
2001
2001
  });
@@ -2055,6 +2055,26 @@ class YumeDatepicker extends HTMLElement {
2055
2055
  _buildHeader(vd, side, isRange) {
2056
2056
  const year = vd.getFullYear();
2057
2057
  const month = vd.getMonth();
2058
+
2059
+ // Month and year picker modes: simple label, no selects or nav
2060
+ if (!this.showDays) {
2061
+ let label;
2062
+ if (this.showMonths) {
2063
+ label = String(year);
2064
+ } else {
2065
+ const minY = this._minDate()?.getFullYear() ?? year - 10;
2066
+ const maxY = this._maxDate()?.getFullYear() ?? year + 10;
2067
+ label = `${minY} – ${maxY}`;
2068
+ }
2069
+ return `
2070
+ <div class="cal-header">
2071
+ <div class="header-selects">
2072
+ <span class="header-label">${label}</span>
2073
+ </div>
2074
+ </div>
2075
+ `;
2076
+ }
2077
+
2058
2078
  const showPrev = !isRange || side === "left";
2059
2079
  const showNext = !isRange || side === "right";
2060
2080
 
@@ -2194,6 +2214,11 @@ class YumeDatepicker extends HTMLElement {
2194
2214
  .month-sel { min-width: 120px; }
2195
2215
  .year-sel { min-width: 80px; }
2196
2216
 
2217
+ .header-label {
2218
+ font-weight: 600;
2219
+ white-space: nowrap;
2220
+ }
2221
+
2197
2222
  /* ---- Day grid ---- */
2198
2223
 
2199
2224
  .day-grid {
@@ -2400,7 +2425,7 @@ class YumeDatepicker extends HTMLElement {
2400
2425
  `;
2401
2426
  }
2402
2427
 
2403
- _emitChange() {
2428
+ _emitChange(source) {
2404
2429
  this._suppressParse = true;
2405
2430
  const value = this._buildValueString();
2406
2431
  if (value !== this.getAttribute("value")) {
@@ -2413,6 +2438,7 @@ class YumeDatepicker extends HTMLElement {
2413
2438
  composed: true,
2414
2439
  detail: {
2415
2440
  value,
2441
+ source,
2416
2442
  startDate: this._startDate
2417
2443
  ? new Date(this._startDate)
2418
2444
  : null,
@@ -2463,7 +2489,7 @@ class YumeDatepicker extends HTMLElement {
2463
2489
  this._startDate = date;
2464
2490
  }
2465
2491
  this._applyTimesToDates();
2466
- this._emitChange();
2492
+ this._emitChange("day");
2467
2493
  this.render();
2468
2494
  }
2469
2495
 
@@ -1,8 +1,8 @@
1
1
  declare namespace _default {
2
- export let title: string;
3
- export let tags: string[];
4
- export { docsParams as parameters };
5
- export namespace argTypes {
2
+ let title: string;
3
+ let tags: string[];
4
+ let decorators: ((story: any) => string)[];
5
+ namespace argTypes {
6
6
  namespace options {
7
7
  let control: string;
8
8
  let description: string;
@@ -111,7 +111,7 @@ declare namespace _default {
111
111
  export { table_6 as table };
112
112
  }
113
113
  }
114
- export namespace args {
114
+ namespace args {
115
115
  export { defaultOptions as options };
116
116
  let value_1: string;
117
117
  export { value_1 as value };
@@ -130,7 +130,7 @@ declare namespace _default {
130
130
  let invalid_1: boolean;
131
131
  export { invalid_1 as invalid };
132
132
  }
133
- export function render({ options, value, placeholder, size, multiple, searchable, clearable, disabled, invalid }: {
133
+ function render({ options, value, placeholder, size, multiple, searchable, clearable, disabled, invalid, }: {
134
134
  options: any;
135
135
  value: any;
136
136
  placeholder: any;
@@ -204,12 +204,4 @@ export namespace Disabled {
204
204
  }
205
205
  export { args_6 as args };
206
206
  }
207
- declare namespace docsParams {
208
- namespace docs {
209
- namespace story {
210
- let inline: boolean;
211
- let height: string;
212
- }
213
- }
214
- }
215
207
  declare const defaultOptions: string;
@@ -396,8 +396,10 @@ class YumeSelect extends HTMLElement {
396
396
  }
397
397
 
398
398
  .dropdown {
399
- position: fixed;
399
+ position: absolute;
400
400
  z-index: var(--component-select-z-index, 6000);
401
+ left: 0;
402
+ right: 0;
401
403
  background: var(--component-select-background);
402
404
  border: var(--component-inputs-border-width) solid var(--component-select-border-color);
403
405
  border-radius: var(--component-inputs-border-radius-outer);
@@ -786,18 +788,14 @@ class YumeSelect extends HTMLElement {
786
788
  _positionDropdown() {
787
789
  const rect = this.selectContainer.getBoundingClientRect();
788
790
  const gap = 4;
789
-
790
- this.dropdown.style.left = `${rect.left}px`;
791
- this.dropdown.style.width = `${rect.width}px`;
792
-
793
- const spaceBelow = window.innerHeight - rect.bottom - gap;
794
791
  const maxH = 200;
792
+ const spaceBelow = window.innerHeight - rect.bottom - gap;
795
793
 
796
794
  if (spaceBelow >= maxH || spaceBelow >= rect.top) {
797
- this.dropdown.style.top = `${rect.bottom + gap}px`;
795
+ this.dropdown.style.top = `${this.selectContainer.offsetHeight + gap}px`;
798
796
  this.dropdown.style.bottom = "auto";
799
797
  } else {
800
- this.dropdown.style.bottom = `${window.innerHeight - rect.top + gap}px`;
798
+ this.dropdown.style.bottom = `${this.selectContainer.offsetHeight + gap}px`;
801
799
  this.dropdown.style.top = "auto";
802
800
  }
803
801
  }