@rokkit/core 1.0.0-next.34 → 1.0.0-next.36
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/package.json +11 -13
- package/src/calendar.js +43 -0
- package/src/connector.js +12 -0
- package/src/constants.js +88 -0
- package/src/index.js +8 -30
- package/src/mapping.js +36 -0
- package/src/nested.js +45 -0
- package/src/ticks.js +16 -0
- package/src/types.js +24 -0
- package/src/utils.js +3 -0
- package/src/EditableTabs.svelte +0 -31
- package/src/ListActions.svelte +0 -35
- package/src/NavTabs.svelte +0 -0
- package/src/NestedPaginator.svelte +0 -64
- package/src/Overlay.svelte +0 -4
- package/src/PageNavigator.svelte +0 -94
- package/src/ResponsiveGrid.svelte +0 -72
- package/src/Scrollable.svelte +0 -8
- package/src/Searchable.svelte +0 -19
- package/src/Sidebar.svelte +0 -5
- package/src/SpinList.svelte +0 -48
- package/src/SplitPane.svelte +0 -109
- package/src/SplitView.svelte +0 -44
- package/src/Splitter.svelte +0 -95
- package/src/TabItem.svelte +0 -30
- package/src/TabItems.svelte +0 -34
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rokkit/core",
|
|
3
|
-
"version": "1.0.0-next.
|
|
3
|
+
"version": "1.0.0-next.36",
|
|
4
4
|
"description": "Core components, actions and stores for svelte apps.",
|
|
5
5
|
"author": "Jerry Thomas <me@jerrythomas.name>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -15,16 +15,17 @@
|
|
|
15
15
|
"devDependencies": {
|
|
16
16
|
"@sveltejs/vite-plugin-svelte": "^2.4.2",
|
|
17
17
|
"@testing-library/svelte": "^4.0.3",
|
|
18
|
-
"@vitest/coverage-c8": "^0.
|
|
19
|
-
"@vitest/coverage-istanbul": "^0.
|
|
20
|
-
"@vitest/
|
|
18
|
+
"@vitest/coverage-c8": "^0.33.0",
|
|
19
|
+
"@vitest/coverage-istanbul": "^0.33.0",
|
|
20
|
+
"@vitest/coverage-v8": "^0.33.0",
|
|
21
|
+
"@vitest/ui": "~0.33.0",
|
|
21
22
|
"jsdom": "^22.1.0",
|
|
22
|
-
"svelte": "^4.0.
|
|
23
|
+
"svelte": "^4.0.5",
|
|
23
24
|
"typescript": "^5.1.6",
|
|
24
25
|
"validators": "latest",
|
|
25
|
-
"vite": "^4.
|
|
26
|
-
"vitest": "~0.
|
|
27
|
-
"shared-config": "1.0.0-next.
|
|
26
|
+
"vite": "^4.4.4",
|
|
27
|
+
"vitest": "~0.33.0",
|
|
28
|
+
"shared-config": "1.0.0-next.36"
|
|
28
29
|
},
|
|
29
30
|
"files": [
|
|
30
31
|
"src/**/*.js",
|
|
@@ -35,8 +36,6 @@
|
|
|
35
36
|
"exports": {
|
|
36
37
|
"./src": "./src",
|
|
37
38
|
"./package.json": "./package.json",
|
|
38
|
-
"./stores": "./src/stores/index.js",
|
|
39
|
-
"./actions": "./src/actions/index.js",
|
|
40
39
|
"./constants": "./src/constants.js",
|
|
41
40
|
".": {
|
|
42
41
|
"types": "./dist/index.d.ts",
|
|
@@ -44,9 +43,8 @@
|
|
|
44
43
|
}
|
|
45
44
|
},
|
|
46
45
|
"dependencies": {
|
|
47
|
-
"
|
|
48
|
-
"ramda": "^0.29.0"
|
|
49
|
-
"rokkit": "1.0.0-next.33"
|
|
46
|
+
"date-fns": "^2.30.0",
|
|
47
|
+
"ramda": "^0.29.0"
|
|
50
48
|
},
|
|
51
49
|
"scripts": {
|
|
52
50
|
"format": "prettier --write .",
|
package/src/calendar.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getDay,
|
|
3
|
+
getMonth,
|
|
4
|
+
getYear,
|
|
5
|
+
getDaysInMonth,
|
|
6
|
+
format,
|
|
7
|
+
isWeekend
|
|
8
|
+
} from 'date-fns'
|
|
9
|
+
|
|
10
|
+
export const weekdays = [
|
|
11
|
+
'Sunday',
|
|
12
|
+
'Monday',
|
|
13
|
+
'Tuesday',
|
|
14
|
+
'Wednesday',
|
|
15
|
+
'Thursday',
|
|
16
|
+
'Friday',
|
|
17
|
+
'Saturday'
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
export function getCalendarDays(value, holidays = [], fixed = false) {
|
|
21
|
+
const month = getMonth(value)
|
|
22
|
+
const year = getYear(value)
|
|
23
|
+
const offset = getDay(new Date(year, month, 1)) + 1
|
|
24
|
+
|
|
25
|
+
holidays = holidays.map((x) => format(new Date(x), 'yyyy-MMM-dd'))
|
|
26
|
+
let days = Array.from({ length: getDaysInMonth(value) }, (_, i) => ({
|
|
27
|
+
day: i + 1,
|
|
28
|
+
offset: i == 0 ? offset : 0,
|
|
29
|
+
date: new Date(year, month, i + 1)
|
|
30
|
+
})).map((x) => ({
|
|
31
|
+
...x,
|
|
32
|
+
text: format(x.date, 'yyyy-MMM-dd'),
|
|
33
|
+
weekend: isWeekend(x.date),
|
|
34
|
+
holiday: holidays.includes(format(x.date, 'yyyy-MMM-dd'))
|
|
35
|
+
}))
|
|
36
|
+
|
|
37
|
+
if (fixed && days[0].offset > 4) {
|
|
38
|
+
const n = 5 * 7 - days[0].offset
|
|
39
|
+
days = [...days.slice(n + 1), ...days.slice(0, n + 1)]
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return days
|
|
43
|
+
}
|
package/src/connector.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function getLineTypes(
|
|
2
|
+
hasChildren = false,
|
|
3
|
+
parentTypes = [],
|
|
4
|
+
position = 'child'
|
|
5
|
+
) {
|
|
6
|
+
let types = parentTypes.slice(0, -1).map((type) => {
|
|
7
|
+
return type === 'child' ? 'sibling' : type === 'last' ? 'empty' : type
|
|
8
|
+
})
|
|
9
|
+
if (parentTypes.length > 0) types.push(position)
|
|
10
|
+
types.push(hasChildren ? 'icon' : 'empty')
|
|
11
|
+
return types
|
|
12
|
+
}
|
package/src/constants.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @type {import('./types).FieldMapping} Fields
|
|
3
|
+
*/
|
|
4
|
+
export const defaultFields = {
|
|
5
|
+
id: 'id',
|
|
6
|
+
url: 'url',
|
|
7
|
+
text: 'text',
|
|
8
|
+
children: 'children',
|
|
9
|
+
icon: 'icon',
|
|
10
|
+
image: 'image',
|
|
11
|
+
component: 'component',
|
|
12
|
+
summary: 'summary',
|
|
13
|
+
notes: 'notes',
|
|
14
|
+
props: 'props',
|
|
15
|
+
target: 'target',
|
|
16
|
+
state: 'state',
|
|
17
|
+
isOpen: '_open',
|
|
18
|
+
isDeleted: '_deleted',
|
|
19
|
+
level: 'level',
|
|
20
|
+
parent: 'parent'
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const defaultIcons = [
|
|
24
|
+
'accordion-opened',
|
|
25
|
+
'accordion-closed',
|
|
26
|
+
'action-remove',
|
|
27
|
+
'action-add',
|
|
28
|
+
'action-clear',
|
|
29
|
+
'action-search',
|
|
30
|
+
'action-close',
|
|
31
|
+
'action-close-filled',
|
|
32
|
+
'node-opened',
|
|
33
|
+
'node-closed',
|
|
34
|
+
'selector-opened',
|
|
35
|
+
'selector-closed',
|
|
36
|
+
'checkbox-checked',
|
|
37
|
+
'checkbox-unchecked',
|
|
38
|
+
'checkbox-unknown',
|
|
39
|
+
'rating-filled',
|
|
40
|
+
'rating-empty',
|
|
41
|
+
'radio-off',
|
|
42
|
+
'radio-on',
|
|
43
|
+
'mode-dark',
|
|
44
|
+
'mode-light',
|
|
45
|
+
'navigate-left',
|
|
46
|
+
'navigate-right',
|
|
47
|
+
'navigate-up',
|
|
48
|
+
'navigate-down',
|
|
49
|
+
'state-error',
|
|
50
|
+
'state-warning',
|
|
51
|
+
'state-success',
|
|
52
|
+
'state-info',
|
|
53
|
+
'state-unknown',
|
|
54
|
+
'validity-failed',
|
|
55
|
+
'validity-warning',
|
|
56
|
+
'validity-passed',
|
|
57
|
+
'validity-unknown'
|
|
58
|
+
]
|
|
59
|
+
|
|
60
|
+
export const defaultOptions = {
|
|
61
|
+
id: 'id',
|
|
62
|
+
label: 'label',
|
|
63
|
+
value: 'value',
|
|
64
|
+
checked: 'checked'
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export const defaultKeyMap = {
|
|
68
|
+
ArrowRight: 'open',
|
|
69
|
+
ArrowLeft: 'close',
|
|
70
|
+
ArrowDown: 'down',
|
|
71
|
+
ArrowUp: 'up',
|
|
72
|
+
Enter: 'select',
|
|
73
|
+
Escape: 'deselect'
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export function stateIconsFromNames(icons) {
|
|
77
|
+
return icons
|
|
78
|
+
.map((k) => [...k.split('-')])
|
|
79
|
+
.reduce(
|
|
80
|
+
(acc, parts) => ({
|
|
81
|
+
...acc,
|
|
82
|
+
[parts[0]]: { ...acc[parts[0]], [parts[1]]: parts.join('-') }
|
|
83
|
+
}),
|
|
84
|
+
{}
|
|
85
|
+
)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export const defaultStateIcons = stateIconsFromNames(defaultIcons)
|
package/src/index.js
CHANGED
|
@@ -1,30 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
// export { default as List } from './List.svelte'
|
|
10
|
-
export { default as Searchable } from './Searchable.svelte'
|
|
11
|
-
export { default as Scrollable } from './Scrollable.svelte'
|
|
12
|
-
// export { default as NestedList } from './NestedList.svelte'
|
|
13
|
-
// export { default as Tabs } from './Tabs.svelte'
|
|
14
|
-
// export { default as BreadCrumbs } from './BreadCrumbs.svelte'
|
|
15
|
-
export { default as NestedPaginator } from './NestedPaginator.svelte'
|
|
16
|
-
|
|
17
|
-
// export { default as Alerts } from './Alerts.svelte'
|
|
18
|
-
// export { default as Slider } from './Slider.svelte'
|
|
19
|
-
// export { default as DropDown } from './DropDown.svelte'
|
|
20
|
-
// export { default as DropSearch } from './DropSearch.svelte'
|
|
21
|
-
export { default as SpinList } from './SpinList.svelte'
|
|
22
|
-
|
|
23
|
-
export { default as Sidebar } from './Sidebar.svelte'
|
|
24
|
-
export { default as SplitPane } from './SplitPane.svelte'
|
|
25
|
-
export { default as Splitter } from './Splitter.svelte'
|
|
26
|
-
export { default as SplitView } from './SplitView.svelte'
|
|
27
|
-
export { default as Overlay } from './Overlay.svelte'
|
|
28
|
-
|
|
29
|
-
export { default as PageNavigator } from './PageNavigator.svelte'
|
|
30
|
-
export { default as ResponsiveGrid } from './ResponsiveGrid.svelte'
|
|
1
|
+
import './types'
|
|
2
|
+
export * from './constants'
|
|
3
|
+
export * from './nested'
|
|
4
|
+
export * from './mapping'
|
|
5
|
+
export * from './connector'
|
|
6
|
+
export * from './ticks'
|
|
7
|
+
export * from './calendar'
|
|
8
|
+
export * from './utils'
|
package/src/mapping.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { defaultFields } from './constants'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Get the component to be used to render the item.
|
|
5
|
+
* If the component is null or undefined, it will return the default component.
|
|
6
|
+
*
|
|
7
|
+
* @param {object|string} value
|
|
8
|
+
* @param {import('./types.js').FieldMapping} fields
|
|
9
|
+
* @param {import('./types.js').ComponentMap} using
|
|
10
|
+
*/
|
|
11
|
+
export function getComponent(value, fields, using) {
|
|
12
|
+
return fields.component && typeof value == 'object'
|
|
13
|
+
? using[value[fields.component]] ?? using.default
|
|
14
|
+
: using.default
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Get the icon for the item. If the icon is an object, it will use the state to determine which icon to use.
|
|
19
|
+
*
|
|
20
|
+
* @param {object|string} value
|
|
21
|
+
* @param {import('./types.js').FieldMapping} fields
|
|
22
|
+
*/
|
|
23
|
+
export function getIcon(value, fields = defaultFields) {
|
|
24
|
+
if (fields.icon === undefined || typeof (value ?? '') !== 'object')
|
|
25
|
+
return null
|
|
26
|
+
|
|
27
|
+
return typeof value[fields.icon] == 'object'
|
|
28
|
+
? value[fields.icon][value[fields.state]]
|
|
29
|
+
: value[fields.icon]
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function getId(node, fields = defaultFields) {
|
|
33
|
+
return typeof node === 'object' && node !== null
|
|
34
|
+
? node[fields.id] ?? node[fields.text]
|
|
35
|
+
: node
|
|
36
|
+
}
|
package/src/nested.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { omit } from 'ramda'
|
|
2
|
+
import { defaultFields } from './constants'
|
|
3
|
+
|
|
4
|
+
export function flattenNestedList(items, fields = defaultFields, level = 0) {
|
|
5
|
+
fields = { ...defaultFields, ...fields }
|
|
6
|
+
let data = []
|
|
7
|
+
items.map((item) => {
|
|
8
|
+
const children = item[fields.children] ?? []
|
|
9
|
+
data = [
|
|
10
|
+
...data,
|
|
11
|
+
{
|
|
12
|
+
...omit([fields.children], item),
|
|
13
|
+
[fields.level]: level,
|
|
14
|
+
[fields.parent]: children.length > 0
|
|
15
|
+
},
|
|
16
|
+
...flattenNestedList(children, fields, level + 1)
|
|
17
|
+
]
|
|
18
|
+
})
|
|
19
|
+
return data
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Converts a path slug to a value in the menu
|
|
24
|
+
*
|
|
25
|
+
* @param {string} slug
|
|
26
|
+
* @returns {any}
|
|
27
|
+
*/
|
|
28
|
+
export function findValueFromPath(slug, data, fields) {
|
|
29
|
+
fields = { ...defaultFields, ...fields }
|
|
30
|
+
const keys = slug.split('/')
|
|
31
|
+
let items = data
|
|
32
|
+
let value = null
|
|
33
|
+
keys.map((key, index) => {
|
|
34
|
+
const match = items.find((item) => item[fields.key] === key)
|
|
35
|
+
if (match) {
|
|
36
|
+
if (index < keys.length - 1) {
|
|
37
|
+
match[fields.isOpen] = true
|
|
38
|
+
items = match[fields.children]
|
|
39
|
+
} else {
|
|
40
|
+
value = match
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
})
|
|
44
|
+
return value
|
|
45
|
+
}
|
package/src/ticks.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export function generateTicks(
|
|
2
|
+
lowerBound,
|
|
3
|
+
upperBound,
|
|
4
|
+
minorTickStep,
|
|
5
|
+
majorTickStep = 1
|
|
6
|
+
) {
|
|
7
|
+
minorTickStep = minorTickStep ? minorTickStep : upperBound - lowerBound
|
|
8
|
+
const length = 1 + Math.ceil((upperBound - lowerBound) / minorTickStep)
|
|
9
|
+
const ticks = Array.from({ length }, (_, i) => ({
|
|
10
|
+
value: i == length - 1 ? upperBound : lowerBound + minorTickStep * i,
|
|
11
|
+
major: i == 0 || i == length - 1 || i % majorTickStep == 0
|
|
12
|
+
}))
|
|
13
|
+
//.map(({ value, show }) => ({ value, label: show ? value : '', major }))
|
|
14
|
+
|
|
15
|
+
return ticks
|
|
16
|
+
}
|
package/src/types.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structure to map custom fields for rendering. This is used to identofy the attributes for various purposes.
|
|
3
|
+
*
|
|
4
|
+
* @typedef FieldMapping
|
|
5
|
+
* @property {string} [id='id'] Unique id for the item
|
|
6
|
+
* @property {string} [text='text'] the text to render
|
|
7
|
+
* @property {string} [url='url'] a URL
|
|
8
|
+
* @property {string} [icon='icon'] icon to render
|
|
9
|
+
* @property {string} [image='image'] the image to render
|
|
10
|
+
* @property {string} [children='children'] children of the item
|
|
11
|
+
* @property {string} [summary='summary']
|
|
12
|
+
* @property {string} [notes='notes']
|
|
13
|
+
* @property {string} [props='props']
|
|
14
|
+
* @property {string} [isOpen='_open'] item is open or closed
|
|
15
|
+
* @property {string} [level='level'] level of item
|
|
16
|
+
* @property {string} [parent='parent'] item is a parent
|
|
17
|
+
* @property {string} [isDeleted='_deleted'] item is deleted
|
|
18
|
+
* @property {FieldMapping} [fields] Field mapping to be used on children in the next level
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Component map to be used to render the item.
|
|
23
|
+
* @typedef {Object<string, import('svelte').SvelteComponent>} ComponentMap
|
|
24
|
+
*/
|
package/src/utils.js
ADDED
package/src/EditableTabs.svelte
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import TabItems from './TabItems.svelte'
|
|
3
|
-
import TabItem from './TabItem.svelte'
|
|
4
|
-
|
|
5
|
-
let className = ''
|
|
6
|
-
export { className as class }
|
|
7
|
-
export let items = []
|
|
8
|
-
export let fields = {}
|
|
9
|
-
export let title = null
|
|
10
|
-
export let allowAdd = false
|
|
11
|
-
export let allowClose = false
|
|
12
|
-
export let value = items[0]
|
|
13
|
-
|
|
14
|
-
function addTab() {
|
|
15
|
-
items = [...items, {}]
|
|
16
|
-
value = items[items.length - 1]
|
|
17
|
-
}
|
|
18
|
-
</script>
|
|
19
|
-
|
|
20
|
-
<tab-view class="flex flex-col w-full flex-grow {className}">
|
|
21
|
-
<tabs class="w-full flex flex-shrink-0 flex-row cursor-pointer select-none">
|
|
22
|
-
{#if title}
|
|
23
|
-
<p>{title}</p>
|
|
24
|
-
{/if}
|
|
25
|
-
<TabItems {items} {fields} {allowClose} bind:value on:close />
|
|
26
|
-
{#if allowAdd}
|
|
27
|
-
<TabItem label="+" on:click={addTab} />
|
|
28
|
-
{/if}
|
|
29
|
-
</tabs>
|
|
30
|
-
<content class="flex flex-grow flex-col"><slot /></content>
|
|
31
|
-
</tab-view>
|
package/src/ListActions.svelte
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
// import Icon from '../layout/Icon.svelte'
|
|
3
|
-
import { createEventDispatcher } from 'svelte'
|
|
4
|
-
import { defaultStateIcons } from 'rokkit/utils'
|
|
5
|
-
|
|
6
|
-
const dispatch = createEventDispatcher()
|
|
7
|
-
|
|
8
|
-
export let search
|
|
9
|
-
export let searchable = true
|
|
10
|
-
export let editable = false
|
|
11
|
-
|
|
12
|
-
const actionIcons = defaultStateIcons.action
|
|
13
|
-
</script>
|
|
14
|
-
|
|
15
|
-
<toolbar class="w-full flex flex-row items-center">
|
|
16
|
-
{#if searchable}
|
|
17
|
-
<search class="flex flex-grow flex-row">
|
|
18
|
-
<icon class={actionIcons.search} />
|
|
19
|
-
<input
|
|
20
|
-
type="search"
|
|
21
|
-
bind:value={search}
|
|
22
|
-
class="rounded-r-full px-3 leading-loose"
|
|
23
|
-
placeholder="search"
|
|
24
|
-
/>
|
|
25
|
-
</search>
|
|
26
|
-
{/if}
|
|
27
|
-
{#if editable}
|
|
28
|
-
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
29
|
-
<icon class={actionIcons.clear} on:click={() => dispatch('clear')} />
|
|
30
|
-
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
31
|
-
<icon class={actionIcons.remove} on:click={() => dispatch('remove')} />
|
|
32
|
-
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
33
|
-
<icon class={actionIcons.add} on:click={() => dispatch('add')} />
|
|
34
|
-
{/if}
|
|
35
|
-
</toolbar>
|
package/src/NavTabs.svelte
DELETED
|
File without changes
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import { defaultFields, flattenNestedList } from 'rokkit/utils'
|
|
3
|
-
import { Item, BreadCrumbs } from '@rokkit/molecules'
|
|
4
|
-
// import { flattenNestedList } from './lib/nested'
|
|
5
|
-
import { createEventDispatcher } from 'svelte'
|
|
6
|
-
|
|
7
|
-
const dispatch = createEventDispatcher()
|
|
8
|
-
export let items
|
|
9
|
-
export let value
|
|
10
|
-
export let fields
|
|
11
|
-
export let using
|
|
12
|
-
|
|
13
|
-
let trail
|
|
14
|
-
let flatList
|
|
15
|
-
|
|
16
|
-
function handleNav(event) {
|
|
17
|
-
let current = flatList.findIndex((item) => item === value)
|
|
18
|
-
let index = current
|
|
19
|
-
if (event === 'previous') {
|
|
20
|
-
while (index > 0 && !flatList[index][fields.key]) {
|
|
21
|
-
index = index - 1
|
|
22
|
-
}
|
|
23
|
-
} else {
|
|
24
|
-
while (index < flatList.length - 1 && !flatList[index][fields.key]) {
|
|
25
|
-
index = index + 1
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
if (flatList[index][fields.key]) {
|
|
29
|
-
value = flatList[index]
|
|
30
|
-
trail = findTrail(flatList, value)
|
|
31
|
-
dispatch('change', { item: value, trail })
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
function findTrail(items, value) {
|
|
35
|
-
let trail = []
|
|
36
|
-
let index = items.findIndex((item) => item === value)
|
|
37
|
-
if (index === -1) return trail
|
|
38
|
-
|
|
39
|
-
let level = items[index][fields.level]
|
|
40
|
-
while (level > 0) {
|
|
41
|
-
trail.unshift(items[index])
|
|
42
|
-
index = items.findIndex(
|
|
43
|
-
(item, i) => i < index && item[fields.level] === level - 1
|
|
44
|
-
)
|
|
45
|
-
level = items[index][fields.level]
|
|
46
|
-
}
|
|
47
|
-
return trail
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
$: flatList = flattenNestedList(items, fields)
|
|
51
|
-
$: fields = { ...defaultFields, ...(fields ?? {}) }
|
|
52
|
-
$: using = { default: Item, ...(using ?? {}) }
|
|
53
|
-
</script>
|
|
54
|
-
|
|
55
|
-
<pages>
|
|
56
|
-
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
57
|
-
<icon
|
|
58
|
-
class="arrow-left cursor-pointer"
|
|
59
|
-
on:click={() => handleNav('previous')}
|
|
60
|
-
/>
|
|
61
|
-
<BreadCrumbs items={trail} {fields} {using} />
|
|
62
|
-
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
63
|
-
<icon class="arrow-right cursor-pointer" on:click={() => handleNav('next')} />
|
|
64
|
-
</pages>
|
package/src/Overlay.svelte
DELETED
package/src/PageNavigator.svelte
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import { createEventDispatcher } from 'svelte'
|
|
3
|
-
import { defaultFields, defaultStateIcons } from 'rokkit/utils'
|
|
4
|
-
import { Icon } from 'rokkit/atoms'
|
|
5
|
-
|
|
6
|
-
const dispatch = createEventDispatcher()
|
|
7
|
-
|
|
8
|
-
let className = ''
|
|
9
|
-
export { className as class }
|
|
10
|
-
|
|
11
|
-
export let items = []
|
|
12
|
-
export let value = items[0]
|
|
13
|
-
export let fields = {}
|
|
14
|
-
export let numbers = false
|
|
15
|
-
|
|
16
|
-
const navigate = defaultStateIcons.navigate
|
|
17
|
-
|
|
18
|
-
let previous
|
|
19
|
-
let next
|
|
20
|
-
|
|
21
|
-
function updateOnChange(value, items) {
|
|
22
|
-
let index = items.findIndex((x) => x == value)
|
|
23
|
-
if (index == -1) value = items[0]
|
|
24
|
-
// } else {
|
|
25
|
-
previous = index > 0 ? items[index - 1] : null
|
|
26
|
-
next = index < items.length - 1 ? items[index + 1] : null
|
|
27
|
-
// }
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
function handleClick(item) {
|
|
31
|
-
if (item) {
|
|
32
|
-
value = item
|
|
33
|
-
dispatch('select', value)
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
$: fields = { ...defaultFields, ...fields }
|
|
38
|
-
$: updateOnChange(value, items)
|
|
39
|
-
|
|
40
|
-
// $: value = items.findIndex((x) => x == value) ? value : items[0]
|
|
41
|
-
</script>
|
|
42
|
-
|
|
43
|
-
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
|
|
44
|
-
<nav-pages class="grid grid-cols-3 select-none {className}" tabindex="0">
|
|
45
|
-
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
46
|
-
<span
|
|
47
|
-
class="flex cursor-pointer items-center"
|
|
48
|
-
on:click={() => handleClick(previous)}
|
|
49
|
-
tabIndex={previous ? 0 : -1}
|
|
50
|
-
>
|
|
51
|
-
{#if previous}
|
|
52
|
-
<Icon name={navigate.left} />
|
|
53
|
-
<p>
|
|
54
|
-
{#if previous[fields.text]}
|
|
55
|
-
{previous[fields.text]}
|
|
56
|
-
{/if}
|
|
57
|
-
</p>
|
|
58
|
-
{/if}
|
|
59
|
-
</span>
|
|
60
|
-
<span class="flex items-center justify-center">
|
|
61
|
-
<block class="flex items-center">
|
|
62
|
-
{#each items as item, index}
|
|
63
|
-
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
64
|
-
<pg
|
|
65
|
-
class:numbers
|
|
66
|
-
class:dot={!numbers}
|
|
67
|
-
class:is-selected={value == item}
|
|
68
|
-
on:click={() => handleClick(item)}
|
|
69
|
-
tabindex="0"
|
|
70
|
-
class="cursor-pointer"
|
|
71
|
-
>
|
|
72
|
-
{#if numbers}
|
|
73
|
-
{index + 1}
|
|
74
|
-
{/if}
|
|
75
|
-
</pg>
|
|
76
|
-
{/each}
|
|
77
|
-
</block>
|
|
78
|
-
</span>
|
|
79
|
-
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
80
|
-
<span
|
|
81
|
-
class="flex cursor-pointer items-center justify-end"
|
|
82
|
-
on:click={() => handleClick(next)}
|
|
83
|
-
tabIndex={next ? 0 : -1}
|
|
84
|
-
>
|
|
85
|
-
{#if next}
|
|
86
|
-
<p class="text-right">
|
|
87
|
-
{#if next[fields.text]}
|
|
88
|
-
{next[fields.text]}
|
|
89
|
-
{/if}
|
|
90
|
-
</p>
|
|
91
|
-
<Icon name={navigate.right} />
|
|
92
|
-
{/if}
|
|
93
|
-
</span>
|
|
94
|
-
</nav-pages>
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import { swipeable, navigable } from 'rokkit/actions'
|
|
3
|
-
import { fly, fade } from 'svelte/transition'
|
|
4
|
-
import { cubicInOut } from 'svelte/easing'
|
|
5
|
-
|
|
6
|
-
let className = 'three-col'
|
|
7
|
-
export { className as class }
|
|
8
|
-
export let items
|
|
9
|
-
export let small = true
|
|
10
|
-
export let duration = 400
|
|
11
|
-
export let easing = cubicInOut
|
|
12
|
-
export let value
|
|
13
|
-
|
|
14
|
-
let previous = -1
|
|
15
|
-
let activeIndex = 0
|
|
16
|
-
let direction = 1
|
|
17
|
-
let width
|
|
18
|
-
|
|
19
|
-
function handleNext() {
|
|
20
|
-
if (activeIndex < items.length - 1) value = items[activeIndex + 1]
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function handlePrevious() {
|
|
24
|
-
if (activeIndex > 0) value = items[activeIndex - 1]
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function activeIndexFromPage(value) {
|
|
28
|
-
const index = items.findIndex((item) => item === value)
|
|
29
|
-
return index > -1 ? index : 0
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
$: activeIndex = activeIndexFromPage(value)
|
|
33
|
-
$: {
|
|
34
|
-
direction = Math.sign(activeIndex - previous)
|
|
35
|
-
previous = activeIndex
|
|
36
|
-
}
|
|
37
|
-
</script>
|
|
38
|
-
|
|
39
|
-
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
|
|
40
|
-
<container
|
|
41
|
-
use:swipeable={{ enabled: small }}
|
|
42
|
-
on:swipeLeft={handleNext}
|
|
43
|
-
on:swipeRight={handlePrevious}
|
|
44
|
-
use:navigable={{ enabled: small }}
|
|
45
|
-
on:previous={handlePrevious}
|
|
46
|
-
on:next={handleNext}
|
|
47
|
-
tabindex={0}
|
|
48
|
-
class="overflow-hidden {className}"
|
|
49
|
-
bind:clientWidth={width}
|
|
50
|
-
>
|
|
51
|
-
{#each items as item, index}
|
|
52
|
-
{@const segmentClass = 'col-' + (index + 1)}
|
|
53
|
-
{@const props = item.props ?? {}}
|
|
54
|
-
{#if small && index === activeIndex}
|
|
55
|
-
<segment
|
|
56
|
-
class="absolute w-full h-full {segmentClass}"
|
|
57
|
-
out:fade={{
|
|
58
|
-
x: -1 * direction * width,
|
|
59
|
-
duration,
|
|
60
|
-
easing
|
|
61
|
-
}}
|
|
62
|
-
in:fly={{ x: direction * width, duration, easing }}
|
|
63
|
-
>
|
|
64
|
-
<svelte:component this={item.component} {...props} />
|
|
65
|
-
</segment>
|
|
66
|
-
{:else if !small}
|
|
67
|
-
<segment class={segmentClass}>
|
|
68
|
-
<svelte:component this={item.component} {...props} />
|
|
69
|
-
</segment>
|
|
70
|
-
{/if}
|
|
71
|
-
{/each}
|
|
72
|
-
</container>
|
package/src/Scrollable.svelte
DELETED
package/src/Searchable.svelte
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import Scrollable from './Scrollable.svelte'
|
|
3
|
-
|
|
4
|
-
export let search = ''
|
|
5
|
-
</script>
|
|
6
|
-
|
|
7
|
-
<div class="searchable h-full w-full flex flex-col overflow-hidden">
|
|
8
|
-
<div class="quick-search flex flex-shrink-0 flex-grow flex-col px-4 py-2">
|
|
9
|
-
<input
|
|
10
|
-
type="search"
|
|
11
|
-
bind:value={search}
|
|
12
|
-
class="rounded-full px-3 leading-loose"
|
|
13
|
-
placeholder="search"
|
|
14
|
-
/>
|
|
15
|
-
</div>
|
|
16
|
-
<Scrollable>
|
|
17
|
-
<slot />
|
|
18
|
-
</Scrollable>
|
|
19
|
-
</div>
|
package/src/Sidebar.svelte
DELETED
package/src/SpinList.svelte
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import { createEventDispatcher } from 'svelte'
|
|
3
|
-
import { defaultFields } from 'rokkit/utils'
|
|
4
|
-
import { Item } from '@rokkit/molecules'
|
|
5
|
-
import { navigable } from 'rokkit/actions'
|
|
6
|
-
// import { getComponent } from './list'
|
|
7
|
-
|
|
8
|
-
const dispatch = createEventDispatcher()
|
|
9
|
-
|
|
10
|
-
let className = ''
|
|
11
|
-
export { className as class }
|
|
12
|
-
export let items = []
|
|
13
|
-
export let fields = {}
|
|
14
|
-
export let using = {}
|
|
15
|
-
export let value
|
|
16
|
-
let index = -1
|
|
17
|
-
|
|
18
|
-
function moveNext() {
|
|
19
|
-
index = index < items.length - 1 ? index + 1 : 0
|
|
20
|
-
dispatch('select', items[index])
|
|
21
|
-
}
|
|
22
|
-
function moveBack() {
|
|
23
|
-
index = index > 0 ? index - 1 : items.length - 1
|
|
24
|
-
dispatch('select', items[index])
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
$: using = { default: Item, ...using }
|
|
28
|
-
$: fields = { ...defaultFields, ...fields }
|
|
29
|
-
$: value = index >= 0 ? items[index] : null
|
|
30
|
-
// $: component = getComponent(value, fields)
|
|
31
|
-
</script>
|
|
32
|
-
|
|
33
|
-
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
|
|
34
|
-
<spin-list class="flex flex-row w-full {className}" tabindex={0}>
|
|
35
|
-
<input
|
|
36
|
-
type="text"
|
|
37
|
-
class="flex flex-grow"
|
|
38
|
-
bind:value
|
|
39
|
-
readonly
|
|
40
|
-
use:navigable
|
|
41
|
-
on:next={moveNext}
|
|
42
|
-
on:previous={moveBack}
|
|
43
|
-
/>
|
|
44
|
-
<!-- <svelte:component this={component} bind:value={value} {fields} on:change /> -->
|
|
45
|
-
<square class="right-0 h-full position-absolute">
|
|
46
|
-
<icon class="i-carbon-chevron-sort" />
|
|
47
|
-
</square>
|
|
48
|
-
</spin-list>
|
package/src/SplitPane.svelte
DELETED
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import { createEventDispatcher } from 'svelte'
|
|
3
|
-
import { pannable } from 'rokkit/actions'
|
|
4
|
-
|
|
5
|
-
const dispatch = createEventDispatcher()
|
|
6
|
-
|
|
7
|
-
export let vertical = false
|
|
8
|
-
export let limits = [50, 30]
|
|
9
|
-
export let pos = 70
|
|
10
|
-
export let styles = ['', '']
|
|
11
|
-
|
|
12
|
-
let refs = {}
|
|
13
|
-
|
|
14
|
-
function clamp(min, max, value) {
|
|
15
|
-
return min > value ? min : max < value ? max : value
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
function handlePanMove(event) {
|
|
19
|
-
const { top, bottom, left, right } = refs.wrapper.getBoundingClientRect()
|
|
20
|
-
const extents = horizontal ? [left, right] : [top, bottom]
|
|
21
|
-
let px = clamp(
|
|
22
|
-
extents[0],
|
|
23
|
-
extents[1],
|
|
24
|
-
horizontal ? event.detail.x : event.detail.y
|
|
25
|
-
)
|
|
26
|
-
pos = clamp(
|
|
27
|
-
limits[0],
|
|
28
|
-
100 - limits[1],
|
|
29
|
-
(100 * (px - extents[0])) / (extents[1] - extents[0])
|
|
30
|
-
)
|
|
31
|
-
dispatch('change', { pos })
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
$: horizontal = !vertical
|
|
35
|
-
$: side = horizontal ? 'left' : 'top'
|
|
36
|
-
$: dimension = horizontal ? 'width' : 'height'
|
|
37
|
-
$: direction = vertical ? 'vertical' : 'horizontal'
|
|
38
|
-
</script>
|
|
39
|
-
|
|
40
|
-
<div class="wrapper {direction}" bind:this={refs.wrapper}>
|
|
41
|
-
<div class={styles[0]} style="{dimension}: {pos}%;">
|
|
42
|
-
<slot name="a" />
|
|
43
|
-
</div>
|
|
44
|
-
<div class={styles[1]} style="{dimension}: {100 - pos}%;">
|
|
45
|
-
<slot name="b" />
|
|
46
|
-
</div>
|
|
47
|
-
<span
|
|
48
|
-
class="wall"
|
|
49
|
-
use:pannable
|
|
50
|
-
on:panmove={handlePanMove}
|
|
51
|
-
style="{side}: calc({pos}% - 8px)"
|
|
52
|
-
/>
|
|
53
|
-
</div>
|
|
54
|
-
|
|
55
|
-
<style>
|
|
56
|
-
.wrapper {
|
|
57
|
-
position: relative;
|
|
58
|
-
display: flex;
|
|
59
|
-
height: 100%;
|
|
60
|
-
width: 100%;
|
|
61
|
-
}
|
|
62
|
-
.wrapper div {
|
|
63
|
-
flex: 1 1 auto;
|
|
64
|
-
height: 100%;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
.horizontal {
|
|
68
|
-
flex-direction: row;
|
|
69
|
-
}
|
|
70
|
-
.vertical {
|
|
71
|
-
flex-direction: column;
|
|
72
|
-
}
|
|
73
|
-
.wall {
|
|
74
|
-
position: absolute;
|
|
75
|
-
z-index: 10;
|
|
76
|
-
}
|
|
77
|
-
.wall::after {
|
|
78
|
-
content: '';
|
|
79
|
-
position: absolute;
|
|
80
|
-
background-color: var(--bg-800);
|
|
81
|
-
}
|
|
82
|
-
.wall:hover {
|
|
83
|
-
cursor: ew-resize;
|
|
84
|
-
}
|
|
85
|
-
.horizontal .wall {
|
|
86
|
-
padding: 0 8px;
|
|
87
|
-
width: 0;
|
|
88
|
-
height: 100%;
|
|
89
|
-
cursor: ew-resize;
|
|
90
|
-
}
|
|
91
|
-
.horizontal .wall::after {
|
|
92
|
-
left: 8px;
|
|
93
|
-
top: 0;
|
|
94
|
-
width: 1px;
|
|
95
|
-
height: 100%;
|
|
96
|
-
}
|
|
97
|
-
.vertical .wall {
|
|
98
|
-
padding: 8px 0;
|
|
99
|
-
width: 100%;
|
|
100
|
-
height: 0;
|
|
101
|
-
cursor: ns-resize;
|
|
102
|
-
}
|
|
103
|
-
.vertical .wall::after {
|
|
104
|
-
top: 8px;
|
|
105
|
-
left: 0;
|
|
106
|
-
width: 100%;
|
|
107
|
-
height: 1px;
|
|
108
|
-
}
|
|
109
|
-
</style>
|
package/src/SplitView.svelte
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import Splitter from './Splitter.svelte'
|
|
3
|
-
|
|
4
|
-
export let vertical = false
|
|
5
|
-
export let min = 30
|
|
6
|
-
export let max = 70
|
|
7
|
-
export let pos = 30
|
|
8
|
-
|
|
9
|
-
$: sizes = [pos, 100 - pos]
|
|
10
|
-
|
|
11
|
-
$: direction = { direction: vertical ? 'flex-col' : 'flex-row' }
|
|
12
|
-
$: sizeA = {
|
|
13
|
-
width: vertical ? 100 : sizes[0],
|
|
14
|
-
height: vertical ? sizes[0] : 100
|
|
15
|
-
}
|
|
16
|
-
$: sizeB = {
|
|
17
|
-
width: vertical ? 100 : sizes[1],
|
|
18
|
-
height: vertical ? sizes[1] : 100
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function onSplitterChange(e) {
|
|
22
|
-
pos = e.detail.pos - e.detail.offset
|
|
23
|
-
}
|
|
24
|
-
</script>
|
|
25
|
-
|
|
26
|
-
<div class="relative h-full w-full flex" style:--direction={direction}>
|
|
27
|
-
<section style:--sizeA={sizeA} class="flex flex-shrink flex-grow select-none">
|
|
28
|
-
<slot name="a" />
|
|
29
|
-
</section>
|
|
30
|
-
<section style:--sizeB={sizeB} class="flex flex-shrink flex-grow select-none">
|
|
31
|
-
<slot name="b" />
|
|
32
|
-
</section>
|
|
33
|
-
<Splitter {vertical} {min} {max} {pos} on:change={onSplitterChange} />
|
|
34
|
-
</div>
|
|
35
|
-
|
|
36
|
-
<style>
|
|
37
|
-
div {
|
|
38
|
-
flex-direction: var(--direction);
|
|
39
|
-
}
|
|
40
|
-
section {
|
|
41
|
-
width: calc(var(--width) * 1%);
|
|
42
|
-
height: calc(var(--height) * 1%);
|
|
43
|
-
}
|
|
44
|
-
</style>
|
package/src/Splitter.svelte
DELETED
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
// ensure that parent has position: relative.
|
|
3
|
-
// on reaching limit remove mouse events.
|
|
4
|
-
import { createEventDispatcher } from 'svelte'
|
|
5
|
-
import { pannable } from 'rokkit/actions'
|
|
6
|
-
|
|
7
|
-
const dispatch = createEventDispatcher()
|
|
8
|
-
|
|
9
|
-
export let vertical = false
|
|
10
|
-
export let index
|
|
11
|
-
export let min = 0
|
|
12
|
-
export let max = 100
|
|
13
|
-
export let pos = 50
|
|
14
|
-
export let offset = 0
|
|
15
|
-
|
|
16
|
-
let wall
|
|
17
|
-
|
|
18
|
-
function clamp(min, max, value) {
|
|
19
|
-
return min > value ? min : max < value ? max : value
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function fixLimits() {
|
|
23
|
-
if (min > max) [min, max] = [max, min]
|
|
24
|
-
max = clamp(0, 100, max)
|
|
25
|
-
min = clamp(0, 100, min)
|
|
26
|
-
pos = clamp(min, max, pos)
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function handlePanMove(event) {
|
|
30
|
-
const { top, bottom, left, right } =
|
|
31
|
-
wall.parentElement.getBoundingClientRect()
|
|
32
|
-
const extents = horizontal ? [left, right] : [top, bottom]
|
|
33
|
-
let px = clamp(
|
|
34
|
-
extents[0],
|
|
35
|
-
extents[1],
|
|
36
|
-
horizontal ? event.detail.x : event.detail.y
|
|
37
|
-
)
|
|
38
|
-
|
|
39
|
-
pos = clamp(min, max, (100 * (px - extents[0])) / (extents[1] - extents[0]))
|
|
40
|
-
|
|
41
|
-
dispatch('change', { pos, index, offset })
|
|
42
|
-
}
|
|
43
|
-
$: fixLimits()
|
|
44
|
-
$: horizontal = !vertical
|
|
45
|
-
$: side = horizontal ? 'left' : 'top'
|
|
46
|
-
</script>
|
|
47
|
-
|
|
48
|
-
<span
|
|
49
|
-
bind:this={wall}
|
|
50
|
-
class="wall"
|
|
51
|
-
class:vertical
|
|
52
|
-
class:horizontal
|
|
53
|
-
use:pannable
|
|
54
|
-
on:panmove={handlePanMove}
|
|
55
|
-
style="{side}: calc({pos}% - 8px)"
|
|
56
|
-
/>
|
|
57
|
-
|
|
58
|
-
<style>
|
|
59
|
-
.wall {
|
|
60
|
-
position: absolute;
|
|
61
|
-
z-index: 10;
|
|
62
|
-
}
|
|
63
|
-
.wall::after {
|
|
64
|
-
content: '';
|
|
65
|
-
position: absolute;
|
|
66
|
-
background-color: #000;
|
|
67
|
-
}
|
|
68
|
-
.wall:hover {
|
|
69
|
-
cursor: ew-resize;
|
|
70
|
-
}
|
|
71
|
-
.horizontal.wall {
|
|
72
|
-
padding: 0 8px;
|
|
73
|
-
width: 0;
|
|
74
|
-
height: 100%;
|
|
75
|
-
cursor: ew-resize;
|
|
76
|
-
}
|
|
77
|
-
.horizontal.wall::after {
|
|
78
|
-
left: 8px;
|
|
79
|
-
top: 0;
|
|
80
|
-
width: 1px;
|
|
81
|
-
height: 100%;
|
|
82
|
-
}
|
|
83
|
-
.vertical.wall {
|
|
84
|
-
padding: 8px 0;
|
|
85
|
-
width: 100%;
|
|
86
|
-
height: 0;
|
|
87
|
-
cursor: ns-resize;
|
|
88
|
-
}
|
|
89
|
-
.vertical.wall::after {
|
|
90
|
-
top: 8px;
|
|
91
|
-
left: 0;
|
|
92
|
-
width: 100%;
|
|
93
|
-
height: 1px;
|
|
94
|
-
}
|
|
95
|
-
</style>
|
package/src/TabItem.svelte
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import { createEventDispatcher } from 'svelte'
|
|
3
|
-
|
|
4
|
-
const dispatch = createEventDispatcher()
|
|
5
|
-
|
|
6
|
-
export let fields = {}
|
|
7
|
-
export let using = {}
|
|
8
|
-
export let value = null
|
|
9
|
-
export let index = 0
|
|
10
|
-
export let icons
|
|
11
|
-
export let selected = false
|
|
12
|
-
export let removable = false
|
|
13
|
-
|
|
14
|
-
$: component = value[fields.component]
|
|
15
|
-
? using[value[fields.component]] || using.default
|
|
16
|
-
: using.default
|
|
17
|
-
</script>
|
|
18
|
-
|
|
19
|
-
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
|
20
|
-
<tab
|
|
21
|
-
class="flex flex-row items-center"
|
|
22
|
-
role="option"
|
|
23
|
-
aria-selected={selected}
|
|
24
|
-
data-path={index}
|
|
25
|
-
>
|
|
26
|
-
<svelte:component this={component} {value} {fields} />
|
|
27
|
-
{#if removable}
|
|
28
|
-
<icon class={icons.close} on:click={() => dispatch('remove')} />
|
|
29
|
-
{/if}
|
|
30
|
-
</tab>
|
package/src/TabItems.svelte
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
<script>
|
|
2
|
-
import { createEventDispatcher } from 'svelte'
|
|
3
|
-
import { defaultFields } from 'rokkit/utils'
|
|
4
|
-
import TabItem from './TabItem.svelte'
|
|
5
|
-
|
|
6
|
-
const dispatch = createEventDispatcher()
|
|
7
|
-
|
|
8
|
-
export let items = []
|
|
9
|
-
export let fields = {}
|
|
10
|
-
export let allowClose = false
|
|
11
|
-
export let value = items[0]
|
|
12
|
-
|
|
13
|
-
function activate(item) {
|
|
14
|
-
value = item
|
|
15
|
-
dispatch('switch', item)
|
|
16
|
-
}
|
|
17
|
-
function closeTab(index) {
|
|
18
|
-
items[index].isClosed = true
|
|
19
|
-
}
|
|
20
|
-
$: fields = { ...defaultFields, ...fields }
|
|
21
|
-
$: filtered = items.filter((item) => !item.isClosed)
|
|
22
|
-
</script>
|
|
23
|
-
|
|
24
|
-
{#each filtered as item, index}
|
|
25
|
-
{@const label = item[fields.text]}
|
|
26
|
-
<TabItem
|
|
27
|
-
icon={item[fields.icon]}
|
|
28
|
-
{label}
|
|
29
|
-
{allowClose}
|
|
30
|
-
active={value == item}
|
|
31
|
-
on:click={() => activate(item)}
|
|
32
|
-
on:close={() => closeTab(index)}
|
|
33
|
-
/>
|
|
34
|
-
{/each}
|