@trdrs/quickcharts 5.4.0 → 5.6.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/CHANGELOG.md +8 -0
- package/README.md +34 -9
- package/dist/feature-manifest.json +1 -1
- package/dist/index.d.ts +23 -5
- package/dist/index.js +67 -21
- package/dist/index.js.map +1 -1
- package/dist/quickcharts.css +81 -16
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 5.6.0
|
|
6
|
+
|
|
7
|
+
The currency and unit box holds its words in a 24px row inside its outline, at the row's start, 3px in from each end on a radius of 3. With `scaleUnitMenu` the row ends in a 7 by 5 caret and lights under the pointer, and `ScaleUnitMenuRequest.expanded(open)` lets the host say its menu stands open, which keeps the row lit and turns the caret up. The auto-scale and logarithmic buttons stand 4px apart, the pair centred on the scale.
|
|
8
|
+
|
|
9
|
+
## 5.5.0
|
|
10
|
+
|
|
11
|
+
The indicator picker's rail offers Favorites only while something is starred, and keeps it while it is open. The author and count columns stand only while a listed row fills them, so a list of starred built-ins reads as stars and names. Items a host answers for the `builtin` collection list in Technicals after the shipped definitions, under the host's own kinds. `IndicatorPickerCollection.empty` gives a collection an empty state: a title, text, a mark drawn 120px square from the 28-unit glyph grid, and one action that reaches `act` with a `collection` target. `IndicatorPickerEmpty` is exported. `chart.indicators.open` takes a `kind` beside `collection` and opens with that kind's filter pressed.
|
|
12
|
+
|
|
5
13
|
## 5.4.0
|
|
6
14
|
|
|
7
15
|
What is drawn over the canvas reads its ink from the canvas's lightness. Over a canvas of the other mode's lightness, such as a white canvas in dark mode, the legend, the scales' boxes and buttons, the pane and navigation buttons and the corner mark wear that mode's built-in colors, and the factory scale text and lines, grid and watermark are that mode's, so they read dark on a light canvas and light on a dark one. A color the host or the viewer named stays theirs.
|
package/README.md
CHANGED
|
@@ -1603,20 +1603,26 @@ part in each through `contributeCapture` (see Extensions).
|
|
|
1603
1603
|
### Indicator picker content
|
|
1604
1604
|
|
|
1605
1605
|
The Indicators button and `commands.execute('chart.indicators.open')` open the same picker.
|
|
1606
|
-
Pass `{ collection: 'saved' }` as the command argument to open a declared host collection directly
|
|
1606
|
+
Pass `{ collection: 'saved' }` as the command argument to open a declared host collection directly,
|
|
1607
|
+
and `kind` beside it (`{ collection: 'builtin', kind: 'template' }`) to open with that kind's filter
|
|
1608
|
+
pressed; a kind neither the chart's `indicator` nor one your source declares leaves every kind listed.
|
|
1607
1609
|
An unknown collection falls back to the shipped catalog. Reopening an already open picker keeps its current selection and query.
|
|
1608
1610
|
The picker opens on the same search field as the symbol search. Beside its list stands a rail of
|
|
1609
|
-
collections: Favorites under Personal, and the 23 shipped definitions as
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1611
|
+
collections: Favorites under Personal while anything is starred, and the 23 shipped definitions as
|
|
1612
|
+
Technicals under Built-in. Favorites stays in the rail while it is open, so unstarring the last row
|
|
1613
|
+
there leaves the trader where they are. Pressing a definition's row adds a new instance to the
|
|
1614
|
+
currently active chart and keeps the picker open. Favorites use your `ChartStorage` port. The list
|
|
1615
|
+
reads as a table of each row's star, name, author, favorite count and actions; the author and count
|
|
1616
|
+
columns stand only while a listed row fills them, so the shipped catalog shows the star, the name
|
|
1617
|
+
and the actions. Escape and a press outside the box close the picker.
|
|
1614
1618
|
|
|
1615
1619
|
Supply `ChartWidgetOptions.indicatorPicker` to include additional localized collections and rows
|
|
1616
1620
|
in that picker. You supply data and opaque actions, not DOM, indicator definitions, or a renderer.
|
|
1617
1621
|
Built-in annotations can add favorite state, counts and actions; they cannot replace a definition,
|
|
1618
|
-
its name, or Add, and their counts show wherever the list is a table
|
|
1619
|
-
|
|
1622
|
+
its name, or Add, and their counts show wherever the list is a table. Items you answer for the
|
|
1623
|
+
`builtin` collection list in Technicals after the shipped definitions, so a kind of your own (see
|
|
1624
|
+
`kinds` below) can stand beside the chart's indicators there. Without a source, the picker has only
|
|
1625
|
+
shipped built-ins and Favorites.
|
|
1620
1626
|
|
|
1621
1627
|
```ts
|
|
1622
1628
|
import type { IndicatorPickerSource } from '@trdrs/quickcharts'
|
|
@@ -1679,6 +1685,23 @@ const withTemplates: IndicatorPickerSource = {
|
|
|
1679
1685
|
}
|
|
1680
1686
|
```
|
|
1681
1687
|
|
|
1688
|
+
A collection can carry an `empty` state for the list to show while it lists nothing and no search
|
|
1689
|
+
is typed: a `title`, optional `text`, an optional `icon` drawn 120px square from the same 28-unit
|
|
1690
|
+
grid as every contributed glyph, and an optional `action`, a button whose press reaches `act` with
|
|
1691
|
+
the target `{ kind: 'collection', id }`. The kind filters step aside while it shows. Without one, an
|
|
1692
|
+
empty collection reads the chart's own no-matches line.
|
|
1693
|
+
|
|
1694
|
+
```ts
|
|
1695
|
+
import type { IndicatorPickerCollection } from '@trdrs/quickcharts'
|
|
1696
|
+
|
|
1697
|
+
const scripts: IndicatorPickerCollection = {
|
|
1698
|
+
id: 'scripts',
|
|
1699
|
+
label: 'My scripts',
|
|
1700
|
+
layout: 'list',
|
|
1701
|
+
empty: { title: 'No scripts yet', text: 'Write one and it lists here.', action: { id: 'create', label: 'Create script' } },
|
|
1702
|
+
}
|
|
1703
|
+
```
|
|
1704
|
+
|
|
1682
1705
|
A favorite action receives the requested next boolean. Successful actions refresh the current
|
|
1683
1706
|
collection unless they return `close: true`. Refusals and exceptions keep the picker open with
|
|
1684
1707
|
plain text, never rendered markup. Icons reuse `ChartExtensionIcon`; invalid icons draw no glyph.
|
|
@@ -2439,7 +2462,9 @@ the same in both modes, in `CHART_FACTORY_COLORS`. The sections and what stands
|
|
|
2439
2462
|
`scaleUnitMenu` option the box is a button titled with the setting's name: a press hands your
|
|
2440
2463
|
handler a `ScaleUnitMenuRequest` (the chart, the box's place in viewport pixels, and whether the
|
|
2441
2464
|
keyboard pressed it) so your own currency and unit menu opens against it, and the box stays
|
|
2442
|
-
while the pointer rests on it.
|
|
2465
|
+
while the pointer rests on it. Call the request's `expanded(true)` as your menu opens and
|
|
2466
|
+
`expanded(false)` as it closes: while it stands open the box stays lit and the caret at the end
|
|
2467
|
+
of its row points up. Without the option the box is a label that takes no pointer, so
|
|
2443
2468
|
the scale under it still drags. The price-to-bar
|
|
2444
2469
|
ratio lock (`lockPriceToBarRatio`) holds the price one bar's width spans: engaging it with no
|
|
2445
2470
|
`priceToBarRatio` of its own takes the ratio on screen into that leaf, the scale stops framing
|
package/dist/index.d.ts
CHANGED
|
@@ -3689,6 +3689,19 @@ interface IndicatorPickerCollection {
|
|
|
3689
3689
|
group?: string;
|
|
3690
3690
|
/** Catalog columns by default; a personal list can omit author and favorite columns. */
|
|
3691
3691
|
layout?: 'table' | 'list';
|
|
3692
|
+
/** What the list shows while the collection lists no row and no search is typed. Omitted, it
|
|
3693
|
+
* reads the chart's own no-matches line. */
|
|
3694
|
+
empty?: IndicatorPickerEmpty;
|
|
3695
|
+
}
|
|
3696
|
+
/** A collection's empty state, centred where its list stands: a mark, a title, a line of text and
|
|
3697
|
+
* one action, which the source's `act` runs with a `collection` target. */
|
|
3698
|
+
interface IndicatorPickerEmpty {
|
|
3699
|
+
title: string;
|
|
3700
|
+
text?: string;
|
|
3701
|
+
/** Drawn 120px square from the same 28-unit grid as every contributed glyph. */
|
|
3702
|
+
icon?: ChartExtensionIcon;
|
|
3703
|
+
/** The empty state's one button. `add` and `favorite` belong to the chart. */
|
|
3704
|
+
action?: IndicatorPickerAction;
|
|
3692
3705
|
}
|
|
3693
3706
|
/** A kind of row a host lists beside the chart's indicators. The picker offers each declared kind as
|
|
3694
3707
|
* a filter under its search field, after All and the chart's own Indicators. */
|
|
@@ -3737,7 +3750,8 @@ interface IndicatorPickerSource {
|
|
|
3737
3750
|
kinds?: readonly IndicatorPickerKind[];
|
|
3738
3751
|
/** The host supplies localized text. A new query or collection aborts the previous read.
|
|
3739
3752
|
* `builtInIds` are the built-ins the picker lists: every one, or those `builtInIndicators`
|
|
3740
|
-
* offers.
|
|
3753
|
+
* offers. Items answered for `builtin` list after the shipped definitions, and items answered
|
|
3754
|
+
* for `favorites` list there when starred. */
|
|
3741
3755
|
list(request: {
|
|
3742
3756
|
collection: string;
|
|
3743
3757
|
query: string;
|
|
@@ -3750,11 +3764,12 @@ interface IndicatorPickerSource {
|
|
|
3750
3764
|
kind: 'unavailable';
|
|
3751
3765
|
message: string;
|
|
3752
3766
|
}>;
|
|
3753
|
-
/** `favorite` carries the requested next value.
|
|
3754
|
-
*
|
|
3767
|
+
/** `favorite` carries the requested next value. A `collection` target is the empty state's action
|
|
3768
|
+
* in the collection of that id. Closing aborts pending work; hosts must also check the signal
|
|
3769
|
+
* before performing late UI effects. Add is never routed here. */
|
|
3755
3770
|
act(request: {
|
|
3756
3771
|
target: {
|
|
3757
|
-
kind: 'builtin' | 'item';
|
|
3772
|
+
kind: 'builtin' | 'item' | 'collection';
|
|
3758
3773
|
id: string;
|
|
3759
3774
|
};
|
|
3760
3775
|
action: string;
|
|
@@ -5593,6 +5608,9 @@ interface ScaleUnitMenuRequest {
|
|
|
5593
5608
|
};
|
|
5594
5609
|
/** Whether the box was pressed from the keyboard, so the menu takes the focus. */
|
|
5595
5610
|
readonly keyboard: boolean;
|
|
5611
|
+
/** Say whether the menu stands open: `true` as it opens and `false` as it closes. While it is open
|
|
5612
|
+
* the box stays lit and its caret points up. */
|
|
5613
|
+
expanded(open: boolean): void;
|
|
5596
5614
|
}
|
|
5597
5615
|
/** Everything needed to construct a widget. `container` and `datafeed` are the two hard
|
|
5598
5616
|
* requirements; every other field has a working default. */
|
|
@@ -6612,4 +6630,4 @@ declare function mountTimeframePicker(options: TimeframePickerOptions & {
|
|
|
6612
6630
|
container: HTMLElement;
|
|
6613
6631
|
}): MountedTimeframePicker;
|
|
6614
6632
|
|
|
6615
|
-
export { ARRANGEMENTS, type AccessPolicy, type ActiveSubsession, type Arrangement, type AttachDrawingsOptions, BRAND_DOWN, BRAND_UP, BUILT_IN_INDICATORS, BUILT_IN_LOCALES, type BuiltInIndicator, CHART_DATE_FORMATS, CHART_FACTORY_COLORS, CHART_ICON_IDS, CHART_SETTINGS_SECTIONS, CHART_STYLES, COLLAPSED_H, COMPARE_COLORS, type CandleStyleSettings, type CanvasTheme, type Capabilities, type ChartBackgroundType, ChartBody, type ChartChrome, type ChartCompareApi, type ChartControlVisibility, type ChartCustomLocale, ChartDatafeed, type ChartDateFormat, type ChartDictionary, type ChartDrawingsApi, type ChartEvents, type ChartExtension, type ChartExtensionCapture, type ChartExtensionCaptureFrame, type ChartExtensionChart, type ChartExtensionCommand, type ChartExtensionContext, type ChartExtensionHandle, type ChartExtensionIcon, type ChartExtensionIconPath, type ChartExtensionLegendRow, type ChartExtensionMenuBuilder, type ChartExtensionMenuContext, type ChartExtensionMenuItem, type ChartExtensionPane, type ChartExtensionPriceLine, type ChartExtensionReplayState, type ChartExtensionScope, type ChartExtensionSeries, type ChartFactoryColors, type ChartHandle, type ChartHistoryApi, type ChartHoursFormat, type ChartI18n, type ChartI18nOptions, type ChartIconArtwork, type ChartIconContext, type ChartIconDiagnostic, type ChartIconFactory, type ChartIconFailure, type ChartIconId, type ChartIcons, type ChartLastValueMode, type ChartLegendRow, type ChartLineColorType, type ChartLocale, type ChartLocaleCode, type ChartMenuAction, type ChartMenuContext, type ChartMenuIcon, type ChartMenuRow, ChartMessageKey, ChartMeta, type ChartPaneSyncApi, type ChartPreferences, type ChartPriceFormatter, type ChartPricePrecision, type ChartPriceSource, type ChartReplayApi, ChartSaveLoadAdapter, type ChartSaveLoadApi, type ChartScalePlacement, type ChartSessionHours, type ChartSettings, type ChartSettingsContribution, type ChartSettingsControls, type ChartSettingsForm, type ChartSettingsIconPainter, type ChartSettingsOption, type ChartSettingsPageId, type ChartSettingsRowHandle, type ChartSettingsSection, type ChartSettingsTip, type ChartStorage, type ChartStrokeStyle, type ChartStyleId, type ChartTimezone, type ChartTitleSource, type ChartTranslate, type ChartWidget, type ChartWidgetOptions, type CommandRegistry, type CommandResult, type CommandScope, type CommandSpec, type CompareDeps, type CompareEntry, type CompareHandle, type ComparePlacement, type CompareSnapshot, type CompareSymbol, type ContextMenuHandle, type CrosshairUi, type CustomThemes, DEFAULT_SUBSESSION, DEFAULT_TIMEZONE, type DataSourceMarkPainter, DataStatus, DatafeedSearchOptions, type DrawingApplyOutcome, DrawingAssetPort, DrawingContextKind, type DrawingDocumentApi, type DrawingDocumentPort, type DrawingDocumentRefusal, type DrawingEvent, type DrawingInks, type DrawingOwner, DrawingPreferences, type DrawingPresets, type DrawingReadOutcome, type DrawingRejection, type DrawingRejectionReason, DrawingResourceContext, DrawingsBody, type DrawingsEvents, type DrawingsHandle, DrawingsMeta, type DrawingsWorkflow, EXCHANGE_TIMEZONE, type FeatureConfig, FeedBar, type FetchLike, FillBetweenPrimitive, type FullscreenApi, type FullscreenOptions, type HistoryChange, type HistoryEventState, IMAGE_HEADER_H, type ImageApi, type ImageEvent, type ImageHeader, type ImageOptions, type ImageTextRun, type ImageTile, type IndicatorCategory, type IndicatorDefinition, type IndicatorEvent, type IndicatorFill, type IndicatorInstance, type IndicatorLevel, type IndicatorManifest, type IndicatorOverrides, type IndicatorPickerAction, type IndicatorPickerBuiltInState, type IndicatorPickerCollection, type IndicatorPickerItem, type IndicatorPickerKind, type IndicatorPickerSource, type IndicatorPlot, type IndicatorPlots, type IndicatorsApi, type IndicatorsRenderer, LAYOUT_MENU_ROWS, type LayoutApi, LayoutBody, type LayoutEvent, LayoutMeta, type LayoutOptions, type LayoutSaveLoadApi, type LayoutSyncFlags, type LegendUi, type LineStyleSettings, type LogicalRange, MAIN_MIN_H, MIN_BAR_SPACING, MIRRORED_ICONS, type ManifestFill, type ManifestInput, type ManifestLevel, type ManifestPlot, type ManifestRun, MarkIconId, type MarkPainters, type MarketStatus, type MatchSegment, type MountedSymbolSearch, type MountedTimeframePicker, type OpenResource, PRICE_SCALE_MODE, type PaneOp, type PanePlan, type PaneRect, type PaneState, type PartialChartSettings, type PlacedImage, type PlotArea, type PlotPoint, PriceFormat, PriceFormatter, RANGE_PRESETS, RECENT_SYMBOLS_CAP, REPLAY_SPEEDS, type RangeFrameTarget, type RangePreset, type RangeSpan, type ReadChartSettings, type RecentsPort, type ReplayEventState, type ReplaySpeed, type ResourceLoadOutcome, ResourceRef, type ResourceRemoveOutcome, type ResourceSaveOutcome, ResourceStore, SCALE_MODES, SCALE_MODE_OPTIONS, SCROLL_STEP_BARS, SESSION_DOT, SESSION_LABEL, SESSION_STATE_TITLE, SPREAD_OPERATORS, type SaveConflictInfo, type ScaleMode, type ScaleUnitMenuRequest, type SearchClassFilter, SearchClassNode, type SearchController, type SearchControllerOptions, type SearchDisplayOptions, SearchPage, type SearchScope, type SearchState, type SelectedDrawing, type SemanticTheme, type SessionBandsPrimitive, type SessionLook, type SessionModel, type SessionSchedule, type SessionSegment, type SessionSource, type SessionState, type SessionTimeline, type SettingsMenuUi, ShadePrimitive, type SpreadOperator, type SpreadOperatorId, type SubsessionSource, SymbolInfo, type SymbolMarkPainter, type SymbolPriceFormat, SymbolRow, type SymbolSearchCache, type SymbolSearchHandle, type SymbolSearchOptions, THEME_ROLES, TIMEFRAME_MAX, TIMEFRAME_PRESETS, TIMEFRAME_PRESET_TOKENS, TIMEFRAME_UNITS, TIMEFRAME_UNIT_NAME, TIMEFRAME_UNIT_SECONDS, TIMEZONES, TOP_BAR_SLOTS, TemplateBody, TemplateMeta, TextDraft, TextEditFrame, type TextEditSession, type TextInlineEdit, type ThemeChangeListener, type ThemeController, type ThemeControllerOptions, type ThemeDeclaration, type ThemeDiagnostic, type ThemeDiagnosticCode, type ThemeMode, type ThemeOptions, type ThemeRole, type ThemeRoleFamily, type ThemeRoleId, type ThemeRoleKind, type ThemeRootStyle, type TimeLabelFormat, type TimeRange, type Timeframe, type TimeframeGroup, type TimeframePickerHandle, type TimeframePickerOptions, type TimeframeRestrictions, type TimeframeUnit, type TimezoneRow, type ToolbarButton, type ToolbarButtonOptions, type ToolbarButtonState, type TopBarSlot, type TopBarUi, type TouchOptions, type TransitionOptions, type UdfDatafeedOptions, type UdfSymbolResponse, type UiConfig, type VenueMarkPainter, type WidgetEvents, ZOOM_FACTOR, type ZoneClock, allowedTimeframes, applyBar, applyPlotOverrides, arrangementName, arrangementOf, attachCompare, attachDrawings, attachIndicators, autoTimeframeFor, buildManifestPlots, canvasTheme, canvasToBlob, chartContextMenu, chartDateSample, chartDictionaries, chartIconArtwork, chartSettingsDefaults, clipToWindow, coerceChartStyle, coerceScaleMode, compareTimeframes, composeFormingBar, composeImage, createChart, createChartI18n, createSearchController, createSessionBands, createSymbolSearchCache, createThemeController, createUdfDatafeed, effectivePlotColor, exchangeTimezoneText, formatChartDate, formatClock, formatDuration, formatTimeframe, frameRange, hasExtendedHours, imageFileName, imageHeaderRuns, imageLayoutHeaderRuns, imageTileRuns, indicatorHidden, isChartStyle, isCollapsed, isIntradayTimeframe, isSymbolPair, isTimezoneChoice, latestPlotValue, layerChartSettings, looksLikeSpread, makeCrosshairTimeFormatter, makeTickMarkFormatter, manifestInputDefaults, marketStatus, marketStatusFor, marketStatusText, marketStatusTitle, matchSegments, memoryChartStorage, memoryRecents, mountContextMenu, mountSymbolSearch, mountTimeframePicker, nextSessionChange, openInputsEditor, openSymbolSearch, openTimeframePicker, overriddenManifest, parseSessionModel, parseTimeframe, pickCompareColor, placeableByWidget, planPaneOp, promoteRecent, rangeAvailable, rangePresetTip, rangeSpanSeconds, readPartialChartSettings, resolveDisplayTimezone, resolveInitialTf, scrolledPosition, seriesTargetOf, sessionBreakTimes, sessionStateAt, sessionTimeline, spreadExpression, spreadSearchQuery, subTimeframesFor, subsessionBarFilter, tfSeconds, tfToUdfResolution, timeframeAllowed, timeframeGroupUnit, timeframeLabel, timeframeOrder, timeframeSeconds, timezoneCity, timezoneLabel, timezoneListing, toolName, tzOffsetLabel, tzOffsetMinutes, udfPriceFormat, udfResolutionToTf, udfSymbolInfo, valueShaped, withFoldedHistory, zoneClock, zoomedBarSpacing };
|
|
6633
|
+
export { ARRANGEMENTS, type AccessPolicy, type ActiveSubsession, type Arrangement, type AttachDrawingsOptions, BRAND_DOWN, BRAND_UP, BUILT_IN_INDICATORS, BUILT_IN_LOCALES, type BuiltInIndicator, CHART_DATE_FORMATS, CHART_FACTORY_COLORS, CHART_ICON_IDS, CHART_SETTINGS_SECTIONS, CHART_STYLES, COLLAPSED_H, COMPARE_COLORS, type CandleStyleSettings, type CanvasTheme, type Capabilities, type ChartBackgroundType, ChartBody, type ChartChrome, type ChartCompareApi, type ChartControlVisibility, type ChartCustomLocale, ChartDatafeed, type ChartDateFormat, type ChartDictionary, type ChartDrawingsApi, type ChartEvents, type ChartExtension, type ChartExtensionCapture, type ChartExtensionCaptureFrame, type ChartExtensionChart, type ChartExtensionCommand, type ChartExtensionContext, type ChartExtensionHandle, type ChartExtensionIcon, type ChartExtensionIconPath, type ChartExtensionLegendRow, type ChartExtensionMenuBuilder, type ChartExtensionMenuContext, type ChartExtensionMenuItem, type ChartExtensionPane, type ChartExtensionPriceLine, type ChartExtensionReplayState, type ChartExtensionScope, type ChartExtensionSeries, type ChartFactoryColors, type ChartHandle, type ChartHistoryApi, type ChartHoursFormat, type ChartI18n, type ChartI18nOptions, type ChartIconArtwork, type ChartIconContext, type ChartIconDiagnostic, type ChartIconFactory, type ChartIconFailure, type ChartIconId, type ChartIcons, type ChartLastValueMode, type ChartLegendRow, type ChartLineColorType, type ChartLocale, type ChartLocaleCode, type ChartMenuAction, type ChartMenuContext, type ChartMenuIcon, type ChartMenuRow, ChartMessageKey, ChartMeta, type ChartPaneSyncApi, type ChartPreferences, type ChartPriceFormatter, type ChartPricePrecision, type ChartPriceSource, type ChartReplayApi, ChartSaveLoadAdapter, type ChartSaveLoadApi, type ChartScalePlacement, type ChartSessionHours, type ChartSettings, type ChartSettingsContribution, type ChartSettingsControls, type ChartSettingsForm, type ChartSettingsIconPainter, type ChartSettingsOption, type ChartSettingsPageId, type ChartSettingsRowHandle, type ChartSettingsSection, type ChartSettingsTip, type ChartStorage, type ChartStrokeStyle, type ChartStyleId, type ChartTimezone, type ChartTitleSource, type ChartTranslate, type ChartWidget, type ChartWidgetOptions, type CommandRegistry, type CommandResult, type CommandScope, type CommandSpec, type CompareDeps, type CompareEntry, type CompareHandle, type ComparePlacement, type CompareSnapshot, type CompareSymbol, type ContextMenuHandle, type CrosshairUi, type CustomThemes, DEFAULT_SUBSESSION, DEFAULT_TIMEZONE, type DataSourceMarkPainter, DataStatus, DatafeedSearchOptions, type DrawingApplyOutcome, DrawingAssetPort, DrawingContextKind, type DrawingDocumentApi, type DrawingDocumentPort, type DrawingDocumentRefusal, type DrawingEvent, type DrawingInks, type DrawingOwner, DrawingPreferences, type DrawingPresets, type DrawingReadOutcome, type DrawingRejection, type DrawingRejectionReason, DrawingResourceContext, DrawingsBody, type DrawingsEvents, type DrawingsHandle, DrawingsMeta, type DrawingsWorkflow, EXCHANGE_TIMEZONE, type FeatureConfig, FeedBar, type FetchLike, FillBetweenPrimitive, type FullscreenApi, type FullscreenOptions, type HistoryChange, type HistoryEventState, IMAGE_HEADER_H, type ImageApi, type ImageEvent, type ImageHeader, type ImageOptions, type ImageTextRun, type ImageTile, type IndicatorCategory, type IndicatorDefinition, type IndicatorEvent, type IndicatorFill, type IndicatorInstance, type IndicatorLevel, type IndicatorManifest, type IndicatorOverrides, type IndicatorPickerAction, type IndicatorPickerBuiltInState, type IndicatorPickerCollection, type IndicatorPickerEmpty, type IndicatorPickerItem, type IndicatorPickerKind, type IndicatorPickerSource, type IndicatorPlot, type IndicatorPlots, type IndicatorsApi, type IndicatorsRenderer, LAYOUT_MENU_ROWS, type LayoutApi, LayoutBody, type LayoutEvent, LayoutMeta, type LayoutOptions, type LayoutSaveLoadApi, type LayoutSyncFlags, type LegendUi, type LineStyleSettings, type LogicalRange, MAIN_MIN_H, MIN_BAR_SPACING, MIRRORED_ICONS, type ManifestFill, type ManifestInput, type ManifestLevel, type ManifestPlot, type ManifestRun, MarkIconId, type MarkPainters, type MarketStatus, type MatchSegment, type MountedSymbolSearch, type MountedTimeframePicker, type OpenResource, PRICE_SCALE_MODE, type PaneOp, type PanePlan, type PaneRect, type PaneState, type PartialChartSettings, type PlacedImage, type PlotArea, type PlotPoint, PriceFormat, PriceFormatter, RANGE_PRESETS, RECENT_SYMBOLS_CAP, REPLAY_SPEEDS, type RangeFrameTarget, type RangePreset, type RangeSpan, type ReadChartSettings, type RecentsPort, type ReplayEventState, type ReplaySpeed, type ResourceLoadOutcome, ResourceRef, type ResourceRemoveOutcome, type ResourceSaveOutcome, ResourceStore, SCALE_MODES, SCALE_MODE_OPTIONS, SCROLL_STEP_BARS, SESSION_DOT, SESSION_LABEL, SESSION_STATE_TITLE, SPREAD_OPERATORS, type SaveConflictInfo, type ScaleMode, type ScaleUnitMenuRequest, type SearchClassFilter, SearchClassNode, type SearchController, type SearchControllerOptions, type SearchDisplayOptions, SearchPage, type SearchScope, type SearchState, type SelectedDrawing, type SemanticTheme, type SessionBandsPrimitive, type SessionLook, type SessionModel, type SessionSchedule, type SessionSegment, type SessionSource, type SessionState, type SessionTimeline, type SettingsMenuUi, ShadePrimitive, type SpreadOperator, type SpreadOperatorId, type SubsessionSource, SymbolInfo, type SymbolMarkPainter, type SymbolPriceFormat, SymbolRow, type SymbolSearchCache, type SymbolSearchHandle, type SymbolSearchOptions, THEME_ROLES, TIMEFRAME_MAX, TIMEFRAME_PRESETS, TIMEFRAME_PRESET_TOKENS, TIMEFRAME_UNITS, TIMEFRAME_UNIT_NAME, TIMEFRAME_UNIT_SECONDS, TIMEZONES, TOP_BAR_SLOTS, TemplateBody, TemplateMeta, TextDraft, TextEditFrame, type TextEditSession, type TextInlineEdit, type ThemeChangeListener, type ThemeController, type ThemeControllerOptions, type ThemeDeclaration, type ThemeDiagnostic, type ThemeDiagnosticCode, type ThemeMode, type ThemeOptions, type ThemeRole, type ThemeRoleFamily, type ThemeRoleId, type ThemeRoleKind, type ThemeRootStyle, type TimeLabelFormat, type TimeRange, type Timeframe, type TimeframeGroup, type TimeframePickerHandle, type TimeframePickerOptions, type TimeframeRestrictions, type TimeframeUnit, type TimezoneRow, type ToolbarButton, type ToolbarButtonOptions, type ToolbarButtonState, type TopBarSlot, type TopBarUi, type TouchOptions, type TransitionOptions, type UdfDatafeedOptions, type UdfSymbolResponse, type UiConfig, type VenueMarkPainter, type WidgetEvents, ZOOM_FACTOR, type ZoneClock, allowedTimeframes, applyBar, applyPlotOverrides, arrangementName, arrangementOf, attachCompare, attachDrawings, attachIndicators, autoTimeframeFor, buildManifestPlots, canvasTheme, canvasToBlob, chartContextMenu, chartDateSample, chartDictionaries, chartIconArtwork, chartSettingsDefaults, clipToWindow, coerceChartStyle, coerceScaleMode, compareTimeframes, composeFormingBar, composeImage, createChart, createChartI18n, createSearchController, createSessionBands, createSymbolSearchCache, createThemeController, createUdfDatafeed, effectivePlotColor, exchangeTimezoneText, formatChartDate, formatClock, formatDuration, formatTimeframe, frameRange, hasExtendedHours, imageFileName, imageHeaderRuns, imageLayoutHeaderRuns, imageTileRuns, indicatorHidden, isChartStyle, isCollapsed, isIntradayTimeframe, isSymbolPair, isTimezoneChoice, latestPlotValue, layerChartSettings, looksLikeSpread, makeCrosshairTimeFormatter, makeTickMarkFormatter, manifestInputDefaults, marketStatus, marketStatusFor, marketStatusText, marketStatusTitle, matchSegments, memoryChartStorage, memoryRecents, mountContextMenu, mountSymbolSearch, mountTimeframePicker, nextSessionChange, openInputsEditor, openSymbolSearch, openTimeframePicker, overriddenManifest, parseSessionModel, parseTimeframe, pickCompareColor, placeableByWidget, planPaneOp, promoteRecent, rangeAvailable, rangePresetTip, rangeSpanSeconds, readPartialChartSettings, resolveDisplayTimezone, resolveInitialTf, scrolledPosition, seriesTargetOf, sessionBreakTimes, sessionStateAt, sessionTimeline, spreadExpression, spreadSearchQuery, subTimeframesFor, subsessionBarFilter, tfSeconds, tfToUdfResolution, timeframeAllowed, timeframeGroupUnit, timeframeLabel, timeframeOrder, timeframeSeconds, timezoneCity, timezoneLabel, timezoneListing, toolName, tzOffsetLabel, tzOffsetMinutes, udfPriceFormat, udfResolutionToTf, udfSymbolInfo, valueShaped, withFoldedHistory, zoneClock, zoomedBarSpacing };
|
package/dist/index.js
CHANGED
|
@@ -8299,15 +8299,15 @@ var drawable = (shape) => {
|
|
|
8299
8299
|
if (rule !== void 0 && rule !== "nonzero" && rule !== "evenodd") return false;
|
|
8300
8300
|
return width === void 0 || Number.isFinite(width) && width > 0 && width <= GLYPH_LIMITS.strokeWidth;
|
|
8301
8301
|
};
|
|
8302
|
-
function buildGlyph(icon) {
|
|
8302
|
+
function buildGlyph(icon, size = GRID) {
|
|
8303
8303
|
try {
|
|
8304
8304
|
const paths = icon && Array.isArray(icon.paths) ? icon.paths : [];
|
|
8305
8305
|
if (paths.length === 0 || paths.length > GLYPH_LIMITS.shapes) return null;
|
|
8306
8306
|
const shapes = paths.filter(drawable);
|
|
8307
8307
|
if (shapes.length === 0) return null;
|
|
8308
8308
|
const root = document.createElementNS(SVG_NS, "svg");
|
|
8309
|
-
set(root, GLYPH_ATTRIBUTES.svg, "width", String(
|
|
8310
|
-
set(root, GLYPH_ATTRIBUTES.svg, "height", String(
|
|
8309
|
+
set(root, GLYPH_ATTRIBUTES.svg, "width", String(size));
|
|
8310
|
+
set(root, GLYPH_ATTRIBUTES.svg, "height", String(size));
|
|
8311
8311
|
set(root, GLYPH_ATTRIBUTES.svg, "viewBox", `0 0 ${GRID} ${GRID}`);
|
|
8312
8312
|
set(root, GLYPH_ATTRIBUTES.svg, "fill", "none");
|
|
8313
8313
|
set(root, GLYPH_ATTRIBUTES.svg, "aria-hidden", "true");
|
|
@@ -10205,6 +10205,9 @@ var ICONS = {
|
|
|
10205
10205
|
/** The pickers' wide caret, on its native 16 by 8 grid: the trigger arrow, which
|
|
10206
10206
|
* renders half size beside a picker's text. */
|
|
10207
10207
|
menuArrowWide: { viewBox: "0 0 16 8", body: solid(polyline([[0.6, 0.7], [8, 7], [15.4, 0.7]], 1.8)) },
|
|
10208
|
+
/** The currency and unit box's caret, on its native 7 by 5 grid: a 1.2 stroke bent down at its
|
|
10209
|
+
* middle, drawn at its own size after the box's words. */
|
|
10210
|
+
scaleUnitArrow: { viewBox: "0 0 7 5", body: '<path d="M1 1.5l2.5 2 2.5-2" stroke="currentColor" stroke-width="1.2"/>' },
|
|
10208
10211
|
// Hairline weight: these two sit beside a label rather than alone in a 38px cell. A tray taking an
|
|
10209
10212
|
// arrow, and two sheets, the back one broken where the front lies over it.
|
|
10210
10213
|
download: { viewBox: "0 0 28 28", body: solid(bend([[6.5, 17], [6.5, 22.5], [22.5, 22.5], [22.5, 17]], 1) + line2([14.5, 6], [14.5, 18]) + polyline([[10.5, 14.5], [14.5, 18.5], [18.5, 14.5]])) },
|
|
@@ -18195,7 +18198,7 @@ var CONTROL_ICONS = byMeaning({
|
|
|
18195
18198
|
image: [ICONS.camera],
|
|
18196
18199
|
download: [ICONS.download],
|
|
18197
18200
|
copy: [ICONS.copy],
|
|
18198
|
-
caret: [ICONS.menuArrowWide],
|
|
18201
|
+
caret: [ICONS.menuArrowWide, ICONS.scaleUnitArrow],
|
|
18199
18202
|
info: [ICONS.info],
|
|
18200
18203
|
// The legend.
|
|
18201
18204
|
visible: [ICONS.legendEye],
|
|
@@ -20435,7 +20438,7 @@ function mountNavControls(deps) {
|
|
|
20435
20438
|
}
|
|
20436
20439
|
|
|
20437
20440
|
// src/ui/chrome/scaleControls.ts
|
|
20438
|
-
var BUTTON = { width: 20, height: 22, gap:
|
|
20441
|
+
var BUTTON = { width: 20, height: 22, gap: 4, foot: 4 };
|
|
20439
20442
|
var UNIT_BOX = { inset: 4 };
|
|
20440
20443
|
function mountScaleControls(deps) {
|
|
20441
20444
|
const t = deps.i18n.t;
|
|
@@ -20445,12 +20448,15 @@ function mountScaleControls(deps) {
|
|
|
20445
20448
|
modes.append(auto, log);
|
|
20446
20449
|
stopPointer(modes);
|
|
20447
20450
|
const door = deps.openUnitMenu;
|
|
20448
|
-
const unit = door ? h("button", { type: "button", class: "qc-scale-unit", "data-role": "scale-unit" }) : h("div", { class: "qc-scale-unit", "data-role": "scale-unit" });
|
|
20451
|
+
const unit = door ? h("button", { type: "button", class: "qc-scale-unit", "data-role": "scale-unit", "aria-haspopup": "menu", "aria-expanded": "false" }) : h("div", { class: "qc-scale-unit", "data-role": "scale-unit" });
|
|
20452
|
+
const unitText = h("span", {});
|
|
20453
|
+
unit.append(h("span", { class: "qc-scale-unit-row" }, unitText, door ? deps.icons.glyph(ICONS.scaleUnitArrow, { size: 7, height: 5, className: "qc-scale-unit-arrow" }) : null));
|
|
20449
20454
|
if (door) {
|
|
20450
20455
|
stopPointer(unit);
|
|
20456
|
+
const expanded = (open2) => unit.setAttribute("aria-expanded", String(open2 === true));
|
|
20451
20457
|
unit.addEventListener("click", (event) => {
|
|
20452
20458
|
const box2 = unit.getBoundingClientRect();
|
|
20453
|
-
door({ left: box2.left, top: box2.top, right: box2.right, bottom: box2.bottom }, event.detail === 0);
|
|
20459
|
+
door({ left: box2.left, top: box2.top, right: box2.right, bottom: box2.bottom }, event.detail === 0, expanded);
|
|
20454
20460
|
});
|
|
20455
20461
|
}
|
|
20456
20462
|
deps.chrome.appendChild(unit);
|
|
@@ -20569,7 +20575,7 @@ function mountScaleControls(deps) {
|
|
|
20569
20575
|
const currency = named2?.currency?.trim() ?? "";
|
|
20570
20576
|
const unitId = named2?.unit?.trim() ?? "";
|
|
20571
20577
|
const text2 = currency && unitId ? t("chrome.currencyAndUnit", { currency, unit: unitId }) : currency || unitId;
|
|
20572
|
-
|
|
20578
|
+
unitText.textContent = text2;
|
|
20573
20579
|
unit.dataset.qcVisibility = visibility;
|
|
20574
20580
|
unit.hidden = text2 === "" || visibility === "never" || visibility === "hover" && !overScale && !overControls;
|
|
20575
20581
|
unit.style.top = `${Math.round(box2.top + UNIT_BOX.inset)}px`;
|
|
@@ -21072,7 +21078,13 @@ function registerChartCommands(deps) {
|
|
|
21072
21078
|
scope: "chart",
|
|
21073
21079
|
label: "chrome.indicators",
|
|
21074
21080
|
available: () => ui.indicatorPicker,
|
|
21075
|
-
execute: (arg) =>
|
|
21081
|
+
execute: (arg) => {
|
|
21082
|
+
const field = (key) => {
|
|
21083
|
+
const value = arg && typeof arg === "object" ? arg[key] : void 0;
|
|
21084
|
+
return typeof value === "string" ? value : void 0;
|
|
21085
|
+
};
|
|
21086
|
+
return deps.indicatorsOpen(field("collection"), field("kind"));
|
|
21087
|
+
}
|
|
21076
21088
|
});
|
|
21077
21089
|
const isInstance = (arg) => !!arg && typeof arg === "object" && typeof arg.id === "string" && typeof arg.definition === "object";
|
|
21078
21090
|
add({
|
|
@@ -22760,6 +22772,7 @@ function createChartInstance(deps) {
|
|
|
22760
22772
|
chrome: chrome2,
|
|
22761
22773
|
gestures,
|
|
22762
22774
|
i18n,
|
|
22775
|
+
icons: deps.icons,
|
|
22763
22776
|
box: priceScaleBox,
|
|
22764
22777
|
modeButtons: () => eff.priceScale.scaleModeButtons,
|
|
22765
22778
|
unitBox: () => eff.priceScale.currencyAndUnit,
|
|
@@ -22776,7 +22789,7 @@ function createChartInstance(deps) {
|
|
|
22776
22789
|
openPriceMenu: (anchor2, keyboard) => {
|
|
22777
22790
|
menu2?.raisePriceMenu(anchor2, keyboard);
|
|
22778
22791
|
},
|
|
22779
|
-
...deps.scaleUnitMenu ? { openUnitMenu: (anchor2, keyboard) => deps.scaleUnitMenu?.({ chart: handle, anchor: anchor2, keyboard }) } : {}
|
|
22792
|
+
...deps.scaleUnitMenu ? { openUnitMenu: (anchor2, keyboard, expanded) => deps.scaleUnitMenu?.({ chart: handle, anchor: anchor2, keyboard, expanded }) } : {}
|
|
22780
22793
|
}) : null;
|
|
22781
22794
|
scalePlus = scaleControls && menu2 ? attachScalePlus({
|
|
22782
22795
|
chart,
|
|
@@ -23821,7 +23834,7 @@ function createChartInstance(deps) {
|
|
|
23821
23834
|
crosshairLevel,
|
|
23822
23835
|
formatter: () => symbolFormatter,
|
|
23823
23836
|
compareOpen: (mode, changeFrom) => compare?.openDialog(mode, changeFrom),
|
|
23824
|
-
indicatorsOpen: (collection) => deps.doors.showIndicatorPicker(collection),
|
|
23837
|
+
indicatorsOpen: (collection, kind) => deps.doors.showIndicatorPicker(collection, kind),
|
|
23825
23838
|
symbolSearchOpen: () => deps.doors.openSearch({ mode: "search", chart: handle }),
|
|
23826
23839
|
drawingVerbs: () => drawings2.verbs
|
|
23827
23840
|
});
|
|
@@ -25596,13 +25609,21 @@ function actions(value) {
|
|
|
25596
25609
|
}
|
|
25597
25610
|
return unique(result.map((a) => a.id)) ? result : null;
|
|
25598
25611
|
}
|
|
25612
|
+
function emptyState2(value) {
|
|
25613
|
+
if (!record2(value) || !text(value.title) || !optionalText(value.text)) return null;
|
|
25614
|
+
const action = value.action === void 0 ? [] : actions([value.action]);
|
|
25615
|
+
if (!action) return null;
|
|
25616
|
+
return { title: value.title, ...value.text !== void 0 ? { text: value.text } : {}, ...value.icon !== void 0 ? { icon: value.icon } : {}, ...action[0] ? { action: action[0] } : {} };
|
|
25617
|
+
}
|
|
25599
25618
|
function pickerCollections(value) {
|
|
25600
25619
|
try {
|
|
25601
25620
|
if (!Array.isArray(value)) return null;
|
|
25602
25621
|
const result = [];
|
|
25603
25622
|
for (const row2 of value) {
|
|
25604
25623
|
if (!record2(row2) || !text(row2.id) || ["builtin", "favorites"].includes(row2.id) || !text(row2.label) || !optionalText(row2.group) || row2.layout !== void 0 && row2.layout !== "list" && row2.layout !== "table") return null;
|
|
25605
|
-
|
|
25624
|
+
const empty = row2.empty === void 0 ? void 0 : emptyState2(row2.empty);
|
|
25625
|
+
if (empty === null) return null;
|
|
25626
|
+
result.push({ id: row2.id, label: row2.label, ...row2.icon !== void 0 ? { icon: row2.icon } : {}, ...row2.group !== void 0 ? { group: row2.group } : {}, ...row2.layout !== void 0 ? { layout: row2.layout } : {}, ...empty ? { empty } : {} });
|
|
25606
25627
|
}
|
|
25607
25628
|
return unique(result.map((row2) => row2.id)) ? result : null;
|
|
25608
25629
|
} catch {
|
|
@@ -25703,8 +25724,10 @@ function openIndicatorPicker(deps) {
|
|
|
25703
25724
|
} catch {
|
|
25704
25725
|
}
|
|
25705
25726
|
let query = "";
|
|
25706
|
-
let
|
|
25707
|
-
|
|
25727
|
+
let hostStarred = false;
|
|
25728
|
+
const starred = () => favorites.length > 0 || hostStarred;
|
|
25729
|
+
let collection = deps.initialCollection === "favorites" && starred() || collections?.some((row2) => row2.id === deps.initialCollection) ? deps.initialCollection : "builtin";
|
|
25730
|
+
let kind = deps.initialKind ?? null;
|
|
25708
25731
|
let generation = 0;
|
|
25709
25732
|
let controller = null;
|
|
25710
25733
|
let busy = false;
|
|
@@ -25744,6 +25767,9 @@ function openIndicatorPicker(deps) {
|
|
|
25744
25767
|
const strip = h("div", { class: "qc-search-classes" });
|
|
25745
25768
|
const nav = h("nav", { class: "qc-picker-nav", "aria-label": t("picker.collections") });
|
|
25746
25769
|
const list = h("div", { class: "qc-picker-list", role: "table", "aria-label": t("picker.title") });
|
|
25770
|
+
const vacant = h("div", { class: "qc-picker-empty" });
|
|
25771
|
+
vacant.hidden = true;
|
|
25772
|
+
let railFavorites = false;
|
|
25747
25773
|
const status2 = h("div", { class: "qc-picker-status qc-secondary", role: "status", "aria-live": "polite" });
|
|
25748
25774
|
let pendingFocus = null;
|
|
25749
25775
|
const actionButton = (label3, content, run, disabled = false, focusKey, className = "qc-picker-action") => {
|
|
@@ -25843,7 +25869,7 @@ function openIndicatorPicker(deps) {
|
|
|
25843
25869
|
else if (focused && focused !== document.body) pendingFocus = null;
|
|
25844
25870
|
const selected = (collections ?? []).find((row2) => row2.id === collection);
|
|
25845
25871
|
list.classList.toggle("qc-picker-list--personal", selected?.layout === "list");
|
|
25846
|
-
|
|
25872
|
+
if (railFavorites !== (starred() || collection === "favorites")) renderNavigation();
|
|
25847
25873
|
for (const button3 of nav.querySelectorAll("[data-picker-collection]")) button3.setAttribute("aria-pressed", String(button3.getAttribute("data-picker-collection") === collection));
|
|
25848
25874
|
for (const chip of strip.querySelectorAll("[data-picker-kind]")) chip.setAttribute("aria-pressed", String((chip.getAttribute("data-picker-kind") || null) === kind));
|
|
25849
25875
|
const headings = h("div", { role: "row", class: "qc-picker-headings" }, ...["", t("picker.name"), t("picker.author"), t("picker.favorites"), ""].map((label3) => h("span", { role: "columnheader" }, label3)));
|
|
@@ -25858,13 +25884,31 @@ function openIndicatorPicker(deps) {
|
|
|
25858
25884
|
body.append(buildRow({ id: definition.id, kind: "builtin", title: t(definition.nameKey), description: t(definition.descriptionKey), favorite, count: metadata?.favoriteCount, hostedFavorite: metadata?.favorite !== void 0 || !!source3 && loading, actions: metadata?.actions ?? [], primary: () => add(definition), permitted: indicatorPermitted(deps.access, definition) && deps.commands.available("chart.indicators.add"), builtin: definition }));
|
|
25859
25885
|
}
|
|
25860
25886
|
}
|
|
25861
|
-
|
|
25887
|
+
for (const item of rows2.items) {
|
|
25862
25888
|
if (collection === "favorites" && item.favorite !== true) continue;
|
|
25863
25889
|
if (!admitted(item.kind ?? INDICATOR_KIND)) continue;
|
|
25864
25890
|
const primary = item.actions.find((action) => action.id === item.primaryAction);
|
|
25865
25891
|
body.append(buildRow({ id: item.id, kind: "item", title: item.title, description: item.description, author: item.author, favorite: item.favorite, count: item.favoriteCount, hostedFavorite: true, actions: item.actions, primary: () => void act({ kind: "item", id: item.id }, primary.id), permitted: !busy && !loading && !primary.disabled }));
|
|
25866
25892
|
}
|
|
25867
25893
|
replace(list, headings, body);
|
|
25894
|
+
const filled = (cell2) => [...body.querySelectorAll(cell2)].some((node) => node.textContent !== "");
|
|
25895
|
+
list.classList.toggle("qc-picker-list--authors", filled(".qc-picker-author"));
|
|
25896
|
+
list.classList.toggle("qc-picker-list--counts", filled(".qc-picker-count"));
|
|
25897
|
+
const empty = selected?.empty && !loading && available && query.trim() === "" && rows2.items.length === 0 ? selected.empty : null;
|
|
25898
|
+
list.hidden = !!empty;
|
|
25899
|
+
vacant.hidden = !empty;
|
|
25900
|
+
strip.hidden = (kinds ?? []).length === 0 || !!empty;
|
|
25901
|
+
if (empty) {
|
|
25902
|
+
const action = empty.action;
|
|
25903
|
+
const mark = buildGlyph(empty.icon, 120);
|
|
25904
|
+
replace(
|
|
25905
|
+
vacant,
|
|
25906
|
+
mark ? h("span", { class: "qc-picker-empty-mark", "aria-hidden": "true" }, mark) : null,
|
|
25907
|
+
h("strong", { class: "qc-picker-empty-title" }, empty.title),
|
|
25908
|
+
empty.text ? h("p", { class: "qc-picker-empty-text" }, empty.text) : null,
|
|
25909
|
+
action ? button2({ label: action.label, text: action.label, className: "qc-button--primary qc-drawing-footer-button qc-picker-empty-action", disabled: busy || action.disabled === true, onClick: () => void act({ kind: "collection", id: collection }, action.id) }) : null
|
|
25910
|
+
);
|
|
25911
|
+
} else replace(vacant);
|
|
25868
25912
|
if (pendingFocus) {
|
|
25869
25913
|
const target = [...list.querySelectorAll("[data-picker-focus]")].find((button3) => button3.dataset.pickerFocus === pendingFocus);
|
|
25870
25914
|
if (target && !target.disabled) target.focus();
|
|
@@ -25873,7 +25917,7 @@ function openIndicatorPicker(deps) {
|
|
|
25873
25917
|
input.focus();
|
|
25874
25918
|
}
|
|
25875
25919
|
}
|
|
25876
|
-
status2.textContent = error || (loading ? t("picker.loading") : body.childElementCount === 0 ? t("picker.noMatches") : "");
|
|
25920
|
+
status2.textContent = error || (loading ? t("picker.loading") : body.childElementCount === 0 && !empty ? t("picker.noMatches") : "");
|
|
25877
25921
|
list.setAttribute("aria-busy", String(loading || busy));
|
|
25878
25922
|
};
|
|
25879
25923
|
const refresh = async () => {
|
|
@@ -25898,6 +25942,7 @@ function openIndicatorPicker(deps) {
|
|
|
25898
25942
|
if (parsed) {
|
|
25899
25943
|
rows2 = parsed;
|
|
25900
25944
|
available = true;
|
|
25945
|
+
hostStarred = parsed.builtIns.some((row2) => row2.favorite === true) || parsed.items.some((item) => item.favorite === true);
|
|
25901
25946
|
} else error = result?.kind === "unavailable" && typeof result.message === "string" && result.message.trim() ? result.message : t("picker.unavailable");
|
|
25902
25947
|
} catch {
|
|
25903
25948
|
if (dialog.open() && revision === generation) error = t("picker.unavailable");
|
|
@@ -25915,8 +25960,9 @@ function openIndicatorPicker(deps) {
|
|
|
25915
25960
|
};
|
|
25916
25961
|
const renderNavigation = () => {
|
|
25917
25962
|
replace(nav);
|
|
25963
|
+
railFavorites = starred() || collection === "favorites";
|
|
25918
25964
|
const personal = t("picker.personal");
|
|
25919
|
-
const navigation = [{ id: "favorites", label: t("picker.favorites"), group: personal, icon: deps.icons.glyph(ICONS.pickerFavorites, { size: 28 }) }, ...(collections ?? []).map((row2) => ({ ...row2, icon: hostIcon(row2.icon) })), { id: "builtin", label: t("picker.technicals"), group: t("picker.builtin"), icon: deps.icons.glyph(ICONS.pickerTechnicals, { size: 28 }) }];
|
|
25965
|
+
const navigation = [...railFavorites ? [{ id: "favorites", label: t("picker.favorites"), group: personal, icon: deps.icons.glyph(ICONS.pickerFavorites, { size: 28 }) }] : [], ...(collections ?? []).map((row2) => ({ ...row2, icon: hostIcon(row2.icon) })), { id: "builtin", label: t("picker.technicals"), group: t("picker.builtin"), icon: deps.icons.glyph(ICONS.pickerTechnicals, { size: 28 }) }];
|
|
25920
25966
|
let section = null;
|
|
25921
25967
|
let group;
|
|
25922
25968
|
for (const item of navigation) {
|
|
@@ -25958,7 +26004,7 @@ function openIndicatorPicker(deps) {
|
|
|
25958
26004
|
input.focus();
|
|
25959
26005
|
} else if (roveFocus(list, event)) event.preventDefault();
|
|
25960
26006
|
});
|
|
25961
|
-
box2.append(searchField(deps.icons, input, clear), strip, h("div", { class: "qc-picker-body" }, nav, h("div", { class: "qc-picker-content" }, list, status2)));
|
|
26007
|
+
box2.append(searchField(deps.icons, input, clear), strip, h("div", { class: "qc-picker-body" }, nav, h("div", { class: "qc-picker-content" }, list, vacant, status2)));
|
|
25962
26008
|
renderKinds();
|
|
25963
26009
|
renderNavigation();
|
|
25964
26010
|
redraw = render;
|
|
@@ -30256,9 +30302,9 @@ function mountChrome(deps) {
|
|
|
30256
30302
|
});
|
|
30257
30303
|
deps.doors.notify = notify;
|
|
30258
30304
|
let indicatorDialog = null;
|
|
30259
|
-
deps.doors.showIndicatorPicker = (initialCollection) => {
|
|
30305
|
+
deps.doors.showIndicatorPicker = (initialCollection, initialKind) => {
|
|
30260
30306
|
if (!ui.indicatorPicker || indicatorDialog?.open()) return;
|
|
30261
|
-
indicatorDialog = openIndicatorPicker({ ...ctx, storage: deps.storage, indicatorPicker: deps.indicatorPicker, initialCollection });
|
|
30307
|
+
indicatorDialog = openIndicatorPicker({ ...ctx, storage: deps.storage, indicatorPicker: deps.indicatorPicker, initialCollection, initialKind });
|
|
30262
30308
|
};
|
|
30263
30309
|
disposers.push(() => {
|
|
30264
30310
|
indicatorDialog?.close({ animate: false });
|