@fusion.dev/helix-core 0.153.0 → 0.155.0
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/custom-elements.json +180 -3
- package/dist/events/details.d.ts +7 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/utils/calendar/calendar.d.ts +45 -0
- package/dist/utils/calendar/calendar.js +102 -0
- package/dist/utils/css-color/css-color.d.ts +23 -6
- package/dist/utils/css-color/css-color.js +59 -1
- package/dist/utils/number-format/number-format.d.ts +1 -1
- package/dist/utils/number-format/number-format.js +1 -1
- package/dist/utils/report-runtime/report-runtime.d.ts +2 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +4 -4
package/custom-elements.json
CHANGED
|
@@ -14633,6 +14633,30 @@
|
|
|
14633
14633
|
"module": "./utils/calendar/calendar.js"
|
|
14634
14634
|
}
|
|
14635
14635
|
},
|
|
14636
|
+
{
|
|
14637
|
+
"kind": "js",
|
|
14638
|
+
"name": "MONTH_CALENDARS",
|
|
14639
|
+
"declaration": {
|
|
14640
|
+
"name": "MONTH_CALENDARS",
|
|
14641
|
+
"module": "./utils/calendar/calendar.js"
|
|
14642
|
+
}
|
|
14643
|
+
},
|
|
14644
|
+
{
|
|
14645
|
+
"kind": "js",
|
|
14646
|
+
"name": "MonthCalendar",
|
|
14647
|
+
"declaration": {
|
|
14648
|
+
"name": "MonthCalendar",
|
|
14649
|
+
"module": "./utils/calendar/calendar.js"
|
|
14650
|
+
}
|
|
14651
|
+
},
|
|
14652
|
+
{
|
|
14653
|
+
"kind": "js",
|
|
14654
|
+
"name": "MonthSystem",
|
|
14655
|
+
"declaration": {
|
|
14656
|
+
"name": "MonthSystem",
|
|
14657
|
+
"module": "./utils/calendar/calendar.js"
|
|
14658
|
+
}
|
|
14659
|
+
},
|
|
14636
14660
|
{
|
|
14637
14661
|
"kind": "js",
|
|
14638
14662
|
"name": "monthOf",
|
|
@@ -14649,6 +14673,14 @@
|
|
|
14649
14673
|
"module": "./utils/calendar/calendar.js"
|
|
14650
14674
|
}
|
|
14651
14675
|
},
|
|
14676
|
+
{
|
|
14677
|
+
"kind": "js",
|
|
14678
|
+
"name": "monthSystem",
|
|
14679
|
+
"declaration": {
|
|
14680
|
+
"name": "monthSystem",
|
|
14681
|
+
"module": "./utils/calendar/calendar.js"
|
|
14682
|
+
}
|
|
14683
|
+
},
|
|
14652
14684
|
{
|
|
14653
14685
|
"kind": "js",
|
|
14654
14686
|
"name": "PeriodCell",
|
|
@@ -14697,6 +14729,22 @@
|
|
|
14697
14729
|
"module": "./utils/calendar/calendar.js"
|
|
14698
14730
|
}
|
|
14699
14731
|
},
|
|
14732
|
+
{
|
|
14733
|
+
"kind": "js",
|
|
14734
|
+
"name": "todayIn",
|
|
14735
|
+
"declaration": {
|
|
14736
|
+
"name": "todayIn",
|
|
14737
|
+
"module": "./utils/calendar/calendar.js"
|
|
14738
|
+
}
|
|
14739
|
+
},
|
|
14740
|
+
{
|
|
14741
|
+
"kind": "js",
|
|
14742
|
+
"name": "weekendOf",
|
|
14743
|
+
"declaration": {
|
|
14744
|
+
"name": "weekendOf",
|
|
14745
|
+
"module": "./utils/calendar/calendar.js"
|
|
14746
|
+
}
|
|
14747
|
+
},
|
|
14700
14748
|
{
|
|
14701
14749
|
"kind": "js",
|
|
14702
14750
|
"name": "weekStartOf",
|
|
@@ -15017,6 +15065,14 @@
|
|
|
15017
15065
|
"module": "./utils/css-color/css-color.js"
|
|
15018
15066
|
}
|
|
15019
15067
|
},
|
|
15068
|
+
{
|
|
15069
|
+
"kind": "js",
|
|
15070
|
+
"name": "toOklch",
|
|
15071
|
+
"declaration": {
|
|
15072
|
+
"name": "toOklch",
|
|
15073
|
+
"module": "./utils/css-color/css-color.js"
|
|
15074
|
+
}
|
|
15075
|
+
},
|
|
15020
15076
|
{
|
|
15021
15077
|
"kind": "js",
|
|
15022
15078
|
"name": "toRgb",
|
|
@@ -23727,6 +23783,44 @@
|
|
|
23727
23783
|
],
|
|
23728
23784
|
"description": "Today, in the reader's own timezone.\n\n**`toISOString` converts to UTC first, which makes \"today\" a different day\nfor most of the planet.** Anywhere west of UTC, from late afternoon onward,\n`fromDate(new Date())` names tomorrow. The parts are read locally instead and\npasted together, which is the only way to get a calendar date out of a `Date`\nwithout a conversion happening on the way."
|
|
23729
23785
|
},
|
|
23786
|
+
{
|
|
23787
|
+
"kind": "function",
|
|
23788
|
+
"name": "todayIn",
|
|
23789
|
+
"return": {
|
|
23790
|
+
"type": {
|
|
23791
|
+
"text": "string"
|
|
23792
|
+
}
|
|
23793
|
+
},
|
|
23794
|
+
"parameters": [
|
|
23795
|
+
{
|
|
23796
|
+
"name": "timeZone",
|
|
23797
|
+
"default": "''"
|
|
23798
|
+
},
|
|
23799
|
+
{
|
|
23800
|
+
"name": "now",
|
|
23801
|
+
"default": "new Date()"
|
|
23802
|
+
}
|
|
23803
|
+
],
|
|
23804
|
+
"description": "Today in a time zone, such as `America/New_York`, as `YYYY-MM-DD`: the\nreader's own where `timeZone` is empty, as `localToday` reads it. A zone\n`Intl` does not know is read as the reader's own too."
|
|
23805
|
+
},
|
|
23806
|
+
{
|
|
23807
|
+
"kind": "function",
|
|
23808
|
+
"name": "weekendOf",
|
|
23809
|
+
"return": {
|
|
23810
|
+
"type": {
|
|
23811
|
+
"text": "number[]"
|
|
23812
|
+
}
|
|
23813
|
+
},
|
|
23814
|
+
"parameters": [
|
|
23815
|
+
{
|
|
23816
|
+
"name": "locale",
|
|
23817
|
+
"type": {
|
|
23818
|
+
"text": "string"
|
|
23819
|
+
}
|
|
23820
|
+
}
|
|
23821
|
+
],
|
|
23822
|
+
"description": "The days of the weekend where a language is spoken, `0` for Sunday.\n\nFrom `Intl.Locale`'s week information, as `weekStartOf` reads it: Friday and\nSaturday in `ar-EG`, Sunday alone in `hi-IN`. Saturday and Sunday where the\nengine offers none."
|
|
23823
|
+
},
|
|
23730
23824
|
{
|
|
23731
23825
|
"kind": "function",
|
|
23732
23826
|
"name": "weekStartOf",
|
|
@@ -23857,6 +23951,31 @@
|
|
|
23857
23951
|
],
|
|
23858
23952
|
"description": "A date some months away, clamped, so the last of a long month lands on the\nlast of a short one instead of rolling into the month after it."
|
|
23859
23953
|
},
|
|
23954
|
+
{
|
|
23955
|
+
"kind": "variable",
|
|
23956
|
+
"name": "MONTH_CALENDARS",
|
|
23957
|
+
"type": {
|
|
23958
|
+
"text": "readonly string[]"
|
|
23959
|
+
},
|
|
23960
|
+
"default": "[ 'coptic', 'ethiopic', 'hebrew', 'indian', 'islamic-civil', 'islamic-umalqura', 'persian', ]",
|
|
23961
|
+
"description": "The `MonthCalendar` names, for a check at run time."
|
|
23962
|
+
},
|
|
23963
|
+
{
|
|
23964
|
+
"kind": "function",
|
|
23965
|
+
"name": "monthSystem",
|
|
23966
|
+
"return": {
|
|
23967
|
+
"type": {
|
|
23968
|
+
"text": "MonthSystem"
|
|
23969
|
+
}
|
|
23970
|
+
},
|
|
23971
|
+
"parameters": [
|
|
23972
|
+
{
|
|
23973
|
+
"name": "calendar",
|
|
23974
|
+
"default": "''"
|
|
23975
|
+
}
|
|
23976
|
+
],
|
|
23977
|
+
"description": "The months a calendar pages through: its own for a `MonthCalendar` name,\nand the Gregorian months for every other."
|
|
23978
|
+
},
|
|
23860
23979
|
{
|
|
23861
23980
|
"kind": "function",
|
|
23862
23981
|
"name": "barredBy",
|
|
@@ -24068,6 +24187,22 @@
|
|
|
24068
24187
|
"module": "src/utils/calendar/calendar.ts"
|
|
24069
24188
|
}
|
|
24070
24189
|
},
|
|
24190
|
+
{
|
|
24191
|
+
"kind": "js",
|
|
24192
|
+
"name": "todayIn",
|
|
24193
|
+
"declaration": {
|
|
24194
|
+
"name": "todayIn",
|
|
24195
|
+
"module": "src/utils/calendar/calendar.ts"
|
|
24196
|
+
}
|
|
24197
|
+
},
|
|
24198
|
+
{
|
|
24199
|
+
"kind": "js",
|
|
24200
|
+
"name": "weekendOf",
|
|
24201
|
+
"declaration": {
|
|
24202
|
+
"name": "weekendOf",
|
|
24203
|
+
"module": "src/utils/calendar/calendar.ts"
|
|
24204
|
+
}
|
|
24205
|
+
},
|
|
24071
24206
|
{
|
|
24072
24207
|
"kind": "js",
|
|
24073
24208
|
"name": "weekStartOf",
|
|
@@ -24116,6 +24251,22 @@
|
|
|
24116
24251
|
"module": "src/utils/calendar/calendar.ts"
|
|
24117
24252
|
}
|
|
24118
24253
|
},
|
|
24254
|
+
{
|
|
24255
|
+
"kind": "js",
|
|
24256
|
+
"name": "MONTH_CALENDARS",
|
|
24257
|
+
"declaration": {
|
|
24258
|
+
"name": "MONTH_CALENDARS",
|
|
24259
|
+
"module": "src/utils/calendar/calendar.ts"
|
|
24260
|
+
}
|
|
24261
|
+
},
|
|
24262
|
+
{
|
|
24263
|
+
"kind": "js",
|
|
24264
|
+
"name": "monthSystem",
|
|
24265
|
+
"declaration": {
|
|
24266
|
+
"name": "monthSystem",
|
|
24267
|
+
"module": "src/utils/calendar/calendar.ts"
|
|
24268
|
+
}
|
|
24269
|
+
},
|
|
24119
24270
|
{
|
|
24120
24271
|
"kind": "js",
|
|
24121
24272
|
"name": "barredBy",
|
|
@@ -25170,6 +25321,24 @@
|
|
|
25170
25321
|
],
|
|
25171
25322
|
"description": "HSB to HSL, which is a different pair of numbers for the same color."
|
|
25172
25323
|
},
|
|
25324
|
+
{
|
|
25325
|
+
"kind": "function",
|
|
25326
|
+
"name": "toOklch",
|
|
25327
|
+
"return": {
|
|
25328
|
+
"type": {
|
|
25329
|
+
"text": "{ chroma: number; hue: number; lightness: number }"
|
|
25330
|
+
}
|
|
25331
|
+
},
|
|
25332
|
+
"parameters": [
|
|
25333
|
+
{
|
|
25334
|
+
"name": "color",
|
|
25335
|
+
"type": {
|
|
25336
|
+
"text": "Color"
|
|
25337
|
+
}
|
|
25338
|
+
}
|
|
25339
|
+
],
|
|
25340
|
+
"description": "Bytes to OKLCH: lightness 0 to 1, chroma from 0, hue in degrees. Björn\nOttosson's OKLab matrices, as CSS Color 4 defines `oklch()`."
|
|
25341
|
+
},
|
|
25173
25342
|
{
|
|
25174
25343
|
"kind": "function",
|
|
25175
25344
|
"name": "parseColor",
|
|
@@ -25254,6 +25423,14 @@
|
|
|
25254
25423
|
"module": "src/utils/css-color/css-color.ts"
|
|
25255
25424
|
}
|
|
25256
25425
|
},
|
|
25426
|
+
{
|
|
25427
|
+
"kind": "js",
|
|
25428
|
+
"name": "toOklch",
|
|
25429
|
+
"declaration": {
|
|
25430
|
+
"name": "toOklch",
|
|
25431
|
+
"module": "src/utils/css-color/css-color.ts"
|
|
25432
|
+
}
|
|
25433
|
+
},
|
|
25257
25434
|
{
|
|
25258
25435
|
"kind": "js",
|
|
25259
25436
|
"name": "parseColor",
|
|
@@ -27826,7 +28003,7 @@
|
|
|
27826
28003
|
"name": "options",
|
|
27827
28004
|
"optional": true,
|
|
27828
28005
|
"type": {
|
|
27829
|
-
"text": "Intl.NumberFormatOptions"
|
|
28006
|
+
"text": "Intl.NumberFormatOptions | null"
|
|
27830
28007
|
}
|
|
27831
28008
|
}
|
|
27832
28009
|
],
|
|
@@ -32230,7 +32407,7 @@
|
|
|
32230
32407
|
"type": {
|
|
32231
32408
|
"text": "string"
|
|
32232
32409
|
},
|
|
32233
|
-
"default": "'0.
|
|
32410
|
+
"default": "'0.155.0'",
|
|
32234
32411
|
"description": "The version of the package this file ships in.\n\n**Written by `fusion/scripts/version.mjs`** wherever it writes the package's\n`package.json`, and stamped back into the repository beside it after a\nrelease, so the two never disagree; a spec beside this holds them to it.\nNothing else in the running code knows which release it is."
|
|
32235
32412
|
}
|
|
32236
32413
|
],
|
|
@@ -32790,6 +32967,6 @@
|
|
|
32790
32967
|
],
|
|
32791
32968
|
"helix": {
|
|
32792
32969
|
"package": "@fusion.dev/helix-core",
|
|
32793
|
-
"version": "0.
|
|
32970
|
+
"version": "0.155.0"
|
|
32794
32971
|
}
|
|
32795
32972
|
}
|
package/dist/events/details.d.ts
CHANGED
|
@@ -281,6 +281,13 @@ export interface ReorderDetail extends ChangeDetail {
|
|
|
281
281
|
keys: string[];
|
|
282
282
|
/** What moved: a column of a data table, an item of a list, or a row of a data table. */
|
|
283
283
|
kind: 'column' | 'item' | 'row';
|
|
284
|
+
/**
|
|
285
|
+
* The key of the branch a tree item moves into, and `''` for the top level,
|
|
286
|
+
* where a `reorderable` tree moves an item into another branch. `keys` are
|
|
287
|
+
* then that branch's items in their new order. Absent for a move among
|
|
288
|
+
* siblings.
|
|
289
|
+
*/
|
|
290
|
+
parent?: string;
|
|
284
291
|
/** Where the key is after the move, counting from 0 in `keys`. */
|
|
285
292
|
to: number;
|
|
286
293
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -56,7 +56,7 @@ export { anchorElement } from './utils/anchor-element/anchor-element.js';
|
|
|
56
56
|
export { arrowReach, sideOf } from './utils/arrow/arrow.js';
|
|
57
57
|
export { assignSlots } from './utils/assign-slots/assign-slots.js';
|
|
58
58
|
export { type DrawAutofillOptions, drawAutofill, } from './utils/autofill-select/autofill-select.js';
|
|
59
|
-
export { addDays, addMonths, type Barring, barredBy, type CalendarView, calendarLocale, type DateCalendar, localToday, monthOf, monthOut, type PeriodCell, type PeriodPage, periodCells, periodKey, periodMove, sameMonth, weekStartOf, YEARS_SHOWN, yearOut, yearPageOf, } from './utils/calendar/calendar.js';
|
|
59
|
+
export { addDays, addMonths, type Barring, barredBy, type CalendarView, calendarLocale, type DateCalendar, localToday, MONTH_CALENDARS, type MonthCalendar, type MonthSystem, monthOf, monthOut, monthSystem, type PeriodCell, type PeriodPage, periodCells, periodKey, periodMove, sameMonth, todayIn, weekendOf, weekStartOf, YEARS_SHOWN, yearOut, yearPageOf, } from './utils/calendar/calendar.js';
|
|
60
60
|
export { capturePointer } from './utils/capture-pointer/capture-pointer.js';
|
|
61
61
|
export { centerInView } from './utils/center-in-view/center-in-view.js';
|
|
62
62
|
export { ariaChord, type ChordPress, chordParts, matchesChord, printableChord, selectsAll, } from './utils/chord/chord.js';
|
|
@@ -68,7 +68,7 @@ export { type ColorWords, colorName, hueName } from './utils/color-name/color-na
|
|
|
68
68
|
export { columnStep } from './utils/column-step/column-step.js';
|
|
69
69
|
export { countLabel } from './utils/count-label/count-label.js';
|
|
70
70
|
export { createSheet } from './utils/create-sheet/create-sheet.js';
|
|
71
|
-
export { type Color, type ColorFormat, formatColor, parseColor, toCss, toHsl, toRgb, } from './utils/css-color/css-color.js';
|
|
71
|
+
export { type Color, type ColorFormat, formatColor, parseColor, toCss, toHsl, toOklch, toRgb, } from './utils/css-color/css-color.js';
|
|
72
72
|
export { customElement, definedTags, duplicateRegistrations, } from './utils/custom-element/custom-element.js';
|
|
73
73
|
export { type DataOption, type DataOptionItem, dataOptions, drawOptions, windowOf, } from './utils/data-options/data-options.js';
|
|
74
74
|
export { segmentName } from './utils/date-segments/date-segments.js';
|
package/dist/index.js
CHANGED
|
@@ -56,7 +56,7 @@ export { anchorElement } from './utils/anchor-element/anchor-element.js';
|
|
|
56
56
|
export { arrowReach, sideOf } from './utils/arrow/arrow.js';
|
|
57
57
|
export { assignSlots } from './utils/assign-slots/assign-slots.js';
|
|
58
58
|
export { drawAutofill, } from './utils/autofill-select/autofill-select.js';
|
|
59
|
-
export { addDays, addMonths, barredBy, calendarLocale, localToday, monthOf, monthOut, periodCells, periodKey, periodMove, sameMonth, weekStartOf, YEARS_SHOWN, yearOut, yearPageOf, } from './utils/calendar/calendar.js';
|
|
59
|
+
export { addDays, addMonths, barredBy, calendarLocale, localToday, MONTH_CALENDARS, monthOf, monthOut, monthSystem, periodCells, periodKey, periodMove, sameMonth, todayIn, weekendOf, weekStartOf, YEARS_SHOWN, yearOut, yearPageOf, } from './utils/calendar/calendar.js';
|
|
60
60
|
export { capturePointer } from './utils/capture-pointer/capture-pointer.js';
|
|
61
61
|
export { centerInView } from './utils/center-in-view/center-in-view.js';
|
|
62
62
|
export { ariaChord, chordParts, matchesChord, printableChord, selectsAll, } from './utils/chord/chord.js';
|
|
@@ -68,7 +68,7 @@ export { colorName, hueName } from './utils/color-name/color-name.js';
|
|
|
68
68
|
export { columnStep } from './utils/column-step/column-step.js';
|
|
69
69
|
export { countLabel } from './utils/count-label/count-label.js';
|
|
70
70
|
export { createSheet } from './utils/create-sheet/create-sheet.js';
|
|
71
|
-
export { formatColor, parseColor, toCss, toHsl, toRgb, } from './utils/css-color/css-color.js';
|
|
71
|
+
export { formatColor, parseColor, toCss, toHsl, toOklch, toRgb, } from './utils/css-color/css-color.js';
|
|
72
72
|
export { customElement, definedTags, duplicateRegistrations, } from './utils/custom-element/custom-element.js';
|
|
73
73
|
export { dataOptions, drawOptions, windowOf, } from './utils/data-options/data-options.js';
|
|
74
74
|
export { segmentName } from './utils/date-segments/date-segments.js';
|
|
@@ -8,6 +8,20 @@
|
|
|
8
8
|
* without a conversion happening on the way.
|
|
9
9
|
*/
|
|
10
10
|
export declare const localToday: (now?: Date) => string;
|
|
11
|
+
/**
|
|
12
|
+
* Today in a time zone, such as `America/New_York`, as `YYYY-MM-DD`: the
|
|
13
|
+
* reader's own where `timeZone` is empty, as `localToday` reads it. A zone
|
|
14
|
+
* `Intl` does not know is read as the reader's own too.
|
|
15
|
+
*/
|
|
16
|
+
export declare const todayIn: (timeZone?: string, now?: Date) => string;
|
|
17
|
+
/**
|
|
18
|
+
* The days of the weekend where a language is spoken, `0` for Sunday.
|
|
19
|
+
*
|
|
20
|
+
* From `Intl.Locale`'s week information, as `weekStartOf` reads it: Friday and
|
|
21
|
+
* Saturday in `ar-EG`, Sunday alone in `hi-IN`. Saturday and Sunday where the
|
|
22
|
+
* engine offers none.
|
|
23
|
+
*/
|
|
24
|
+
export declare const weekendOf: (locale: string) => number[];
|
|
11
25
|
/**
|
|
12
26
|
* The first day of the week where a language is spoken, `0` for Sunday.
|
|
13
27
|
*
|
|
@@ -54,6 +68,37 @@ export declare const sameMonth: (left: Date, right: Date) => boolean;
|
|
|
54
68
|
* last of a short one instead of rolling into the month after it.
|
|
55
69
|
*/
|
|
56
70
|
export declare const addMonths: (date: Date, months: number) => Date;
|
|
71
|
+
/**
|
|
72
|
+
* The calendars Date Picker draws with months of their own, when `calendar`
|
|
73
|
+
* names one: the months of the year in Iran, Israel, Saudi Arabia, Ethiopia,
|
|
74
|
+
* Egypt's Coptic church, and India's national calendar. React Aria's
|
|
75
|
+
* `createCalendar` offers the same set.
|
|
76
|
+
*/
|
|
77
|
+
export type MonthCalendar = 'coptic' | 'ethiopic' | 'hebrew' | 'indian' | 'islamic-civil' | 'islamic-umalqura' | 'persian';
|
|
78
|
+
/** The `MonthCalendar` names, for a check at run time. */
|
|
79
|
+
export declare const MONTH_CALENDARS: readonly string[];
|
|
80
|
+
/**
|
|
81
|
+
* The months of a calendar, as Date Picker pages through them. Every date is
|
|
82
|
+
* still a Gregorian `Date` at midnight UTC, and a month is the run of days
|
|
83
|
+
* from its first.
|
|
84
|
+
*/
|
|
85
|
+
export interface MonthSystem {
|
|
86
|
+
/** A date some months away, its day kept where the month is long enough. */
|
|
87
|
+
add(date: Date, months: number): Date;
|
|
88
|
+
/** The day of its month, from 1. */
|
|
89
|
+
day(date: Date): number;
|
|
90
|
+
/** The month a date is in, as `month` writes it: `YYYY-MM`, or its first day where the months are the calendar's own. */
|
|
91
|
+
key(date: Date): string;
|
|
92
|
+
/** Whether two dates fall in one month. */
|
|
93
|
+
same(left: Date, right: Date): boolean;
|
|
94
|
+
/** The first day of the month a date is in. */
|
|
95
|
+
start(date: Date): Date;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* The months a calendar pages through: its own for a `MonthCalendar` name,
|
|
99
|
+
* and the Gregorian months for every other.
|
|
100
|
+
*/
|
|
101
|
+
export declare const monthSystem: (calendar?: string) => MonthSystem;
|
|
57
102
|
/** What bars a date, besides `min` and `max`. */
|
|
58
103
|
export interface Barring {
|
|
59
104
|
/** Dates as `YYYY-MM-DD`, separated by commas or spaces. */
|
|
@@ -5,6 +5,34 @@ export const localToday = (now = new Date()) => {
|
|
|
5
5
|
const day = `${now.getDate()}`.padStart(2, '0');
|
|
6
6
|
return `${now.getFullYear()}-${month}-${day}`;
|
|
7
7
|
};
|
|
8
|
+
export const todayIn = (timeZone = '', now = new Date()) => {
|
|
9
|
+
if (timeZone === '') {
|
|
10
|
+
return localToday(now);
|
|
11
|
+
}
|
|
12
|
+
try {
|
|
13
|
+
const parts = new Intl.DateTimeFormat('en-US', {
|
|
14
|
+
day: '2-digit',
|
|
15
|
+
month: '2-digit',
|
|
16
|
+
timeZone,
|
|
17
|
+
year: 'numeric',
|
|
18
|
+
}).formatToParts(now);
|
|
19
|
+
const part = (type) => parts.find((one) => one.type === type)?.value ?? '';
|
|
20
|
+
return `${part('year').padStart(4, '0')}-${part('month')}-${part('day')}`;
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return localToday(now);
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
export const weekendOf = (locale) => {
|
|
27
|
+
try {
|
|
28
|
+
const tag = new Intl.Locale(locale);
|
|
29
|
+
const days = tag.getWeekInfo?.().weekend ?? tag.weekInfo?.weekend;
|
|
30
|
+
return days === undefined ? [0, 6] : days.map((day) => day % 7);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return [0, 6];
|
|
34
|
+
}
|
|
35
|
+
};
|
|
8
36
|
export const weekStartOf = (locale) => {
|
|
9
37
|
try {
|
|
10
38
|
const tag = new Intl.Locale(locale);
|
|
@@ -40,6 +68,80 @@ export const addMonths = (date, months) => {
|
|
|
40
68
|
const last = utcDate(target.getUTCFullYear(), target.getUTCMonth() + 1, 0).getUTCDate();
|
|
41
69
|
return utcDate(target.getUTCFullYear(), target.getUTCMonth(), Math.min(date.getUTCDate(), last));
|
|
42
70
|
};
|
|
71
|
+
export const MONTH_CALENDARS = [
|
|
72
|
+
'coptic',
|
|
73
|
+
'ethiopic',
|
|
74
|
+
'hebrew',
|
|
75
|
+
'indian',
|
|
76
|
+
'islamic-civil',
|
|
77
|
+
'islamic-umalqura',
|
|
78
|
+
'persian',
|
|
79
|
+
];
|
|
80
|
+
const GREGORIAN = {
|
|
81
|
+
add: (date, months) => addMonths(date, months),
|
|
82
|
+
day: (date) => date.getUTCDate(),
|
|
83
|
+
key: (date) => monthOf(date),
|
|
84
|
+
same: (left, right) => sameMonth(left, right),
|
|
85
|
+
start: (date) => utcDate(date.getUTCFullYear(), date.getUTCMonth(), 1),
|
|
86
|
+
};
|
|
87
|
+
const intlMonths = (calendar) => {
|
|
88
|
+
const format = new Intl.DateTimeFormat(`en-u-ca-${calendar}-nu-latn`, {
|
|
89
|
+
day: 'numeric',
|
|
90
|
+
timeZone: 'UTC',
|
|
91
|
+
});
|
|
92
|
+
const days = new Map();
|
|
93
|
+
const day = (date) => {
|
|
94
|
+
const at = date.getTime();
|
|
95
|
+
let found = days.get(at);
|
|
96
|
+
if (found === undefined) {
|
|
97
|
+
found = Number(format.formatToParts(date).find((part) => part.type === 'day')?.value);
|
|
98
|
+
if (days.size > 4000) {
|
|
99
|
+
days.clear();
|
|
100
|
+
}
|
|
101
|
+
days.set(at, found);
|
|
102
|
+
}
|
|
103
|
+
return found;
|
|
104
|
+
};
|
|
105
|
+
const start = (date) => addDays(date, 1 - day(date));
|
|
106
|
+
const length = (first) => {
|
|
107
|
+
for (const count of [29, 30, 31, 28, 32]) {
|
|
108
|
+
if (day(addDays(first, count)) === 1 && day(addDays(first, count - 1)) === count) {
|
|
109
|
+
return count;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
for (let count = 1; count < 28; count += 1) {
|
|
113
|
+
if (day(addDays(first, count)) === 1) {
|
|
114
|
+
return count;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return 30;
|
|
118
|
+
};
|
|
119
|
+
return {
|
|
120
|
+
add: (date, months) => {
|
|
121
|
+
let first = start(date);
|
|
122
|
+
for (let step = 0; step < Math.abs(months); step += 1) {
|
|
123
|
+
first = months > 0 ? addDays(first, length(first)) : start(addDays(first, -1));
|
|
124
|
+
}
|
|
125
|
+
return addDays(first, Math.min(day(date), length(first)) - 1);
|
|
126
|
+
},
|
|
127
|
+
day,
|
|
128
|
+
key: (date) => fromDate(start(date)),
|
|
129
|
+
same: (left, right) => start(left).getTime() === start(right).getTime(),
|
|
130
|
+
start,
|
|
131
|
+
};
|
|
132
|
+
};
|
|
133
|
+
const systems = new Map();
|
|
134
|
+
export const monthSystem = (calendar = '') => {
|
|
135
|
+
if (!MONTH_CALENDARS.includes(calendar)) {
|
|
136
|
+
return GREGORIAN;
|
|
137
|
+
}
|
|
138
|
+
let system = systems.get(calendar);
|
|
139
|
+
if (system === undefined) {
|
|
140
|
+
system = intlMonths(calendar);
|
|
141
|
+
systems.set(calendar, system);
|
|
142
|
+
}
|
|
143
|
+
return system;
|
|
144
|
+
};
|
|
43
145
|
export const barredBy = (date, rules) => {
|
|
44
146
|
const iso = fromDate(date);
|
|
45
147
|
if (writtenList(rules.disableDates).includes(iso) ||
|
|
@@ -7,12 +7,20 @@
|
|
|
7
7
|
* expect, since full saturation in HSL is a mid-lightness band rather than a
|
|
8
8
|
* corner.
|
|
9
9
|
*
|
|
10
|
-
* **Every syntax here is read
|
|
10
|
+
* **Every syntax here is read and written.** A field that refuses
|
|
11
11
|
* `rgb(255 0 0)` because it prefers hex is a field arguing with the person using
|
|
12
|
-
* it, so the space-separated forms, the comma forms, `rgba
|
|
13
|
-
* taken. What is written back is whichever of hex, rgb
|
|
14
|
-
* set to, so a value stays in the shape the
|
|
15
|
-
* entered.
|
|
12
|
+
* it, so the space-separated forms, the comma forms, `rgba`, `hsla`, `hsba` and
|
|
13
|
+
* `oklch` are all taken. What is written back is whichever of hex, rgb, hsl,
|
|
14
|
+
* hsb or oklch the component is set to, so a value stays in the shape the
|
|
15
|
+
* consumer asked for however it was entered.
|
|
16
|
+
*
|
|
17
|
+
* **`oklch` is read into sRGB.** The working model is sRGB, so a color outside
|
|
18
|
+
* it, such as a display-P3 green written in `oklch`, is clipped to the nearest
|
|
19
|
+
* sRGB channel values. What is written in `oklch` is that sRGB color, exactly.
|
|
20
|
+
*
|
|
21
|
+
* `hsb()` is not CSS. It is the working model written out, as React Aria's and
|
|
22
|
+
* Zag's color strings write it, for a value handed to code that thinks in hue,
|
|
23
|
+
* saturation and brightness. A stylesheet wants one of the other three.
|
|
16
24
|
*
|
|
17
25
|
* **What is written is the comma form.** Both are valid, and the commas are what
|
|
18
26
|
* a reader recognizes, what most code around them holds, and what pastes into
|
|
@@ -40,7 +48,7 @@ export interface Color {
|
|
|
40
48
|
saturation: number;
|
|
41
49
|
}
|
|
42
50
|
/** The syntaxes a value can be written in. */
|
|
43
|
-
export type ColorFormat = 'hex' | 'hsl' | 'rgb';
|
|
51
|
+
export type ColorFormat = 'hex' | 'hsb' | 'hsl' | 'oklch' | 'rgb';
|
|
44
52
|
/** HSB to bytes, which is the road every written syntax goes down. */
|
|
45
53
|
export declare const toRgb: (color: Color) => {
|
|
46
54
|
blue: number;
|
|
@@ -53,6 +61,15 @@ export declare const toHsl: (color: Color) => {
|
|
|
53
61
|
lightness: number;
|
|
54
62
|
saturation: number;
|
|
55
63
|
};
|
|
64
|
+
/**
|
|
65
|
+
* Bytes to OKLCH: lightness 0 to 1, chroma from 0, hue in degrees. Björn
|
|
66
|
+
* Ottosson's OKLab matrices, as CSS Color 4 defines `oklch()`.
|
|
67
|
+
*/
|
|
68
|
+
export declare const toOklch: (color: Color) => {
|
|
69
|
+
chroma: number;
|
|
70
|
+
hue: number;
|
|
71
|
+
lightness: number;
|
|
72
|
+
};
|
|
56
73
|
/**
|
|
57
74
|
* Any of the syntaxes to the working model, or `null` where it is not a color.
|
|
58
75
|
*
|
|
@@ -74,6 +74,40 @@ export const toHsl = (color) => {
|
|
|
74
74
|
: (brightness - lightness) / Math.min(lightness, 1 - lightness)) * 100),
|
|
75
75
|
};
|
|
76
76
|
};
|
|
77
|
+
const linear = (channel) => channel <= 0.04045 ? channel / 12.92 : ((channel + 0.055) / 1.055) ** 2.4;
|
|
78
|
+
const gamma = (channel) => channel <= 0.0031308 ? channel * 12.92 : 1.055 * channel ** (1 / 2.4) - 0.055;
|
|
79
|
+
export const toOklch = (color) => {
|
|
80
|
+
const { blue, green, red } = toRgb(color);
|
|
81
|
+
const [r, g, b] = [red, green, blue].map((one) => linear(one / 255));
|
|
82
|
+
const l = Math.cbrt(0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b);
|
|
83
|
+
const m = Math.cbrt(0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b);
|
|
84
|
+
const s = Math.cbrt(0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b);
|
|
85
|
+
const lightness = 0.2104542553 * l + 0.793617785 * m - 0.0040720468 * s;
|
|
86
|
+
const a = 1.9779984951 * l - 2.428592205 * m + 0.4505937099 * s;
|
|
87
|
+
const bb = 0.0259040371 * l + 0.7827717662 * m - 0.808675766 * s;
|
|
88
|
+
const chroma = Math.hypot(a, bb);
|
|
89
|
+
const hue = chroma < 0.0001 ? 0 : ((((Math.atan2(bb, a) * 180) / Math.PI) % 360) + 360) % 360;
|
|
90
|
+
return { chroma, hue, lightness };
|
|
91
|
+
};
|
|
92
|
+
const oklchToRgb = (lightness, chroma, hue) => {
|
|
93
|
+
const angle = (hue * Math.PI) / 180;
|
|
94
|
+
const a = chroma * Math.cos(angle);
|
|
95
|
+
const b = chroma * Math.sin(angle);
|
|
96
|
+
const l = (lightness + 0.3963377774 * a + 0.2158037573 * b) ** 3;
|
|
97
|
+
const m = (lightness - 0.1055613458 * a - 0.0638541728 * b) ** 3;
|
|
98
|
+
const s = (lightness - 0.0894841775 * a - 1.291485548 * b) ** 3;
|
|
99
|
+
return [
|
|
100
|
+
4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,
|
|
101
|
+
-1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,
|
|
102
|
+
-0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s,
|
|
103
|
+
].map((one) => Math.round(clamp(gamma(clamp(one, 0, 1)), 0, 1) * 255));
|
|
104
|
+
};
|
|
105
|
+
const oklchParts = (first, second, third) => {
|
|
106
|
+
const number = (token) => (token === 'none' ? 0 : Number.parseFloat(token));
|
|
107
|
+
const lightness = first.endsWith('%') ? number(first) / 100 : number(first);
|
|
108
|
+
const chroma = second.endsWith('%') ? (number(second) / 100) * 0.4 : number(second);
|
|
109
|
+
return [clamp(lightness, 0, 1), Math.max(0, chroma), number(third)];
|
|
110
|
+
};
|
|
77
111
|
export const parseColor = (value) => {
|
|
78
112
|
const text = value.trim().toLowerCase();
|
|
79
113
|
if (text === '') {
|
|
@@ -94,7 +128,7 @@ export const parseColor = (value) => {
|
|
|
94
128
|
const carriesAlpha = digits.length === 4 || digits.length === 8;
|
|
95
129
|
return rgbToHsb(channel(0), channel(1), channel(2), carriesAlpha ? Math.round((channel(3) / 255) * 100) : 100);
|
|
96
130
|
}
|
|
97
|
-
const call = /^(rgba?|hsla
|
|
131
|
+
const call = /^(rgba?|hsla?|hsba?|oklch)\(([^)]*)\)$/.exec(text);
|
|
98
132
|
if (!call?.[1] || call[2] === undefined) {
|
|
99
133
|
return null;
|
|
100
134
|
}
|
|
@@ -109,12 +143,27 @@ export const parseColor = (value) => {
|
|
|
109
143
|
if (call[1].startsWith('rgb')) {
|
|
110
144
|
return rgbToHsb(toByte(first), toByte(second), toByte(third), alpha);
|
|
111
145
|
}
|
|
146
|
+
if (call[1] === 'oklch') {
|
|
147
|
+
const parts = oklchParts(first, second, third);
|
|
148
|
+
if (parts.some(Number.isNaN)) {
|
|
149
|
+
return null;
|
|
150
|
+
}
|
|
151
|
+
return rgbToHsb(...oklchToRgb(...parts), alpha);
|
|
152
|
+
}
|
|
112
153
|
const hue = Number.parseFloat(first);
|
|
113
154
|
const saturation = clamp(Number.parseFloat(second), 0, 100) / 100;
|
|
114
155
|
const lightness = clamp(Number.parseFloat(third), 0, 100) / 100;
|
|
115
156
|
if (Number.isNaN(hue) || Number.isNaN(saturation) || Number.isNaN(lightness)) {
|
|
116
157
|
return null;
|
|
117
158
|
}
|
|
159
|
+
if (call[1].startsWith('hsb')) {
|
|
160
|
+
return {
|
|
161
|
+
alpha,
|
|
162
|
+
brightness: Math.round(lightness * 100),
|
|
163
|
+
hue: Math.round(((hue % 360) + 360) % 360),
|
|
164
|
+
saturation: Math.round(saturation * 100),
|
|
165
|
+
};
|
|
166
|
+
}
|
|
118
167
|
const brightness = lightness + saturation * Math.min(lightness, 1 - lightness);
|
|
119
168
|
return {
|
|
120
169
|
alpha,
|
|
@@ -126,6 +175,15 @@ export const parseColor = (value) => {
|
|
|
126
175
|
export const formatColor = (color, format, withAlpha) => {
|
|
127
176
|
const alpha = clamp(color.alpha, 0, 100) / 100;
|
|
128
177
|
const opacity = Number(alpha.toFixed(2));
|
|
178
|
+
if (format === 'oklch') {
|
|
179
|
+
const { chroma, hue, lightness } = toOklch(color);
|
|
180
|
+
const body = `${Number((lightness * 100).toFixed(1))}% ${Number(chroma.toFixed(3))} ${Number(hue.toFixed(1))}`;
|
|
181
|
+
return withAlpha ? `oklch(${body} / ${opacity})` : `oklch(${body})`;
|
|
182
|
+
}
|
|
183
|
+
if (format === 'hsb') {
|
|
184
|
+
const body = `${Math.round(((color.hue % 360) + 360) % 360)}, ${Math.round(clamp(color.saturation, 0, 100))}%, ${Math.round(clamp(color.brightness, 0, 100))}%`;
|
|
185
|
+
return withAlpha ? `hsba(${body}, ${opacity})` : `hsb(${body})`;
|
|
186
|
+
}
|
|
129
187
|
if (format === 'hsl') {
|
|
130
188
|
const { hue, lightness, saturation } = toHsl(color);
|
|
131
189
|
const body = `${Math.round(hue)}, ${saturation}%, ${lightness}%`;
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* build and cheap to call, and a control formats on every update.
|
|
9
9
|
*/
|
|
10
10
|
/** Writes a number in a locale with `Intl.NumberFormat` options. */
|
|
11
|
-
export declare const formatNumber: (value: number, locale?: string, options?: Intl.NumberFormatOptions) => string;
|
|
11
|
+
export declare const formatNumber: (value: number, locale?: string, options?: Intl.NumberFormatOptions | null) => string;
|
|
12
12
|
/**
|
|
13
13
|
* A share, from 0 to 1, as a locale writes a whole percentage: `40%`, or
|
|
14
14
|
* `40 %` in French. For `aria-valuetext`, since a bare `aria-valuenow` is read
|
|
@@ -3,7 +3,7 @@ const formatter = (locale, options) => {
|
|
|
3
3
|
const key = `${locale}|${JSON.stringify(options ?? {})}`;
|
|
4
4
|
let found = held.get(key);
|
|
5
5
|
if (!found) {
|
|
6
|
-
found = new Intl.NumberFormat(locale || undefined, options);
|
|
6
|
+
found = new Intl.NumberFormat(locale || undefined, options ?? undefined);
|
|
7
7
|
held.set(key, found);
|
|
8
8
|
}
|
|
9
9
|
return found;
|
|
@@ -22,6 +22,8 @@ export type RuntimeKind =
|
|
|
22
22
|
'cite-not-url'
|
|
23
23
|
/** A deprecated property, attribute or slot was used; the message names what replaces it. */
|
|
24
24
|
| 'deprecated'
|
|
25
|
+
/** Two landmarks of one kind share a name, so a screen reader lists them alike. */
|
|
26
|
+
| 'duplicate-name'
|
|
25
27
|
/** Another class asked for a tag that is already registered: two copies of Helix. */
|
|
26
28
|
| 'duplicate-registration'
|
|
27
29
|
/** The browser refused fullscreen, usually for a frame without the permission. */
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const VERSION = '0.
|
|
1
|
+
export const VERSION = '0.155.0';
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fusion.dev/helix-core",
|
|
3
3
|
"description": "Helix element primitives: base classes, mixins, decorators, utilities.",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.155.0",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Ross Sheppard <ross.sheppard@fusion.dev>",
|
|
7
7
|
"repository": {
|
|
@@ -56,11 +56,11 @@
|
|
|
56
56
|
"bugs": "https://github.com/project-fusion/fusion/issues",
|
|
57
57
|
"dependencies": {
|
|
58
58
|
"@floating-ui/dom": "^1.8.0",
|
|
59
|
-
"@fusion.dev/helix-icons": "0.
|
|
59
|
+
"@fusion.dev/helix-icons": "0.155.0"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
|
-
"@fusion.dev/helix-cem": "0.
|
|
63
|
-
"@fusion.dev/helix-testing": "0.
|
|
62
|
+
"@fusion.dev/helix-cem": "0.155.0",
|
|
63
|
+
"@fusion.dev/helix-testing": "0.155.0",
|
|
64
64
|
"@lit-labs/ssr": "^4.1.0",
|
|
65
65
|
"lit": "^3.2.1"
|
|
66
66
|
},
|