瀏覽代碼

Update range styles

Resort to vanilla styling.
pull/1/head
TheoryOfNekomata 1 年之前
父節點
當前提交
b7378efe51
共有 12 個檔案被更改,包括 515 行新增440 行删除
  1. +1
    -1
      packages/web-kitchensink-reactnext/package.json
  2. +131
    -46
      packages/web-kitchensink-reactnext/pnpm-lock.yaml
  3. +1
    -1
      packages/web-kitchensink-reactnext/src/base/selectcontrol/index.ts
  4. +14
    -9
      packages/web-kitchensink-reactnext/src/categories/blob/react/components/AudioFilePreview/index.tsx
  5. +19
    -17
      packages/web-kitchensink-reactnext/src/categories/blob/react/components/TextFilePreview/index.tsx
  6. +14
    -9
      packages/web-kitchensink-reactnext/src/categories/blob/react/components/VideoFilePreview/index.tsx
  7. +189
    -19
      packages/web-kitchensink-reactnext/src/categories/number/react/components/Slider/index.tsx
  8. +55
    -18
      packages/web-kitchensink-reactnext/src/categories/number/react/components/Slider/style.module.css
  9. +17
    -5
      packages/web-kitchensink-reactnext/src/packages/react-binary-data-canvas/index.tsx
  10. +19
    -80
      packages/web-kitchensink-reactnext/src/packages/react-prism/index.tsx
  11. +36
    -222
      packages/web-kitchensink-reactnext/src/pages/categories/number/index.tsx
  12. +19
    -13
      packages/web-kitchensink-reactnext/src/styles/globals.css

+ 1
- 1
packages/web-kitchensink-reactnext/package.json 查看文件

@@ -9,7 +9,6 @@
"lint": "next lint"
},
"dependencies": {
"@reach/slider": "^0.18.0",
"@theoryofnekomata/formxtra": "^1.0.3",
"@types/node": "20.3.1",
"@types/react": "18.2.14",
@@ -26,6 +25,7 @@
"prismjs": "^1.29.0",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-refractor": "^2.1.7",
"tailwindcss": "3.3.2",
"typescript": "5.1.3",
"wavesurfer.js": "7.0.0-beta.11"


+ 131
- 46
packages/web-kitchensink-reactnext/pnpm-lock.yaml 查看文件

@@ -1,13 +1,10 @@
lockfileVersion: '6.1'
lockfileVersion: '6.0'

settings:
autoInstallPeers: true
excludeLinksFromLockfile: false

dependencies:
'@reach/slider':
specifier: ^0.18.0
version: 0.18.0(react-dom@18.2.0)(react@18.2.0)
'@theoryofnekomata/formxtra':
specifier: ^1.0.3
version: 1.0.3
@@ -56,6 +53,9 @@ dependencies:
react-dom:
specifier: 18.2.0
version: 18.2.0(react@18.2.0)
react-refractor:
specifier: ^2.1.7
version: 2.1.7(react@18.2.0)
tailwindcss:
specifier: 3.3.2
version: 3.3.2
@@ -310,48 +310,6 @@ packages:
tslib: 2.5.3
dev: false

/@reach/auto-id@0.18.0(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-XwY1IwhM7mkHZFghhjiqjQ6dstbOdpbFLdggeke75u8/8icT8uEHLbovFUgzKjy9qPvYwZIB87rLiR8WdtOXCg==}
peerDependencies:
react: ^16.8.0 || 17.x
react-dom: ^16.8.0 || 17.x
dependencies:
'@reach/utils': 0.18.0(react-dom@18.2.0)(react@18.2.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
dev: false

/@reach/polymorphic@0.18.0(react@18.2.0):
resolution: {integrity: sha512-N9iAjdMbE//6rryZZxAPLRorzDcGBnluf7YQij6XDLiMtfCj1noa7KyLpEc/5XCIB/EwhX3zCluFAwloBKdblA==}
peerDependencies:
react: ^16.8.0 || 17.x
dependencies:
react: 18.2.0
dev: false

/@reach/slider@0.18.0(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-DLq8ziZn74P/puY0F2tO7fR67PPp7/MIiydfvUdB3kefmn8ewXMUrY7tO6sdhVXk2y2Jtncd5PO1NStPn1QFfw==}
peerDependencies:
react: ^16.9.0 || 17.x
react-dom: ^16.9.0 || 17.x
dependencies:
'@reach/auto-id': 0.18.0(react-dom@18.2.0)(react@18.2.0)
'@reach/polymorphic': 0.18.0(react@18.2.0)
'@reach/utils': 0.18.0(react-dom@18.2.0)(react@18.2.0)
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
dev: false

/@reach/utils@0.18.0(react-dom@18.2.0)(react@18.2.0):
resolution: {integrity: sha512-KdVMdpTgDyK8FzdKO9SCpiibuy/kbv3pwgfXshTI6tEcQT1OOwj7BAksnzGC0rPz0UholwC+AgkqEl3EJX3M1A==}
peerDependencies:
react: ^16.8.0 || 17.x
react-dom: ^16.8.0 || 17.x
dependencies:
react: 18.2.0
react-dom: 18.2.0(react@18.2.0)
dev: false

/@rushstack/eslint-patch@1.3.2:
resolution: {integrity: sha512-V+MvGwaHH03hYhY+k6Ef/xKd6RYlc4q8WBx+2ANmipHJcKuktNcI/NgEsJgdSUF6Lw32njT6OnrRsKYCdgHjYw==}
dev: false
@@ -371,6 +329,12 @@ packages:
resolution: {integrity: sha512-epMsEE85fi4lfmJUH/89/iV/LI+F5CvNIvmgs5g5jYFPfhO2S/ae8WSsLOKWdwtoaZw9Q2IhJ4tQ5tFCcS/4HA==}
dev: true

/@types/hast@2.3.4:
resolution: {integrity: sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==}
dependencies:
'@types/unist': 2.0.6
dev: false

/@types/json5@0.0.29:
resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==}
dev: false
@@ -409,6 +373,10 @@ packages:
resolution: {integrity: sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==}
dev: false

/@types/unist@2.0.6:
resolution: {integrity: sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==}
dev: false

/@types/wavesurfer.js@6.0.6:
resolution: {integrity: sha512-fD54o0RXZXxkOb+69Rt6rGViaHpIc1Mmde2aOX9qPhlQhrCPepybGnsekiG407+7scPlaK+hmuPez5AnnmlzGg==}
dependencies:
@@ -749,6 +717,18 @@ packages:
supports-color: 7.2.0
dev: false

/character-entities-legacy@1.1.4:
resolution: {integrity: sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==}
dev: false

/character-entities@1.2.4:
resolution: {integrity: sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==}
dev: false

/character-reference-invalid@1.1.4:
resolution: {integrity: sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==}
dev: false

/chokidar@3.5.3:
resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==}
engines: {node: '>= 8.10.0'}
@@ -798,6 +778,10 @@ packages:
delayed-stream: 1.0.0
dev: false

/comma-separated-tokens@1.0.8:
resolution: {integrity: sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==}
dev: false

/commander@4.1.1:
resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
engines: {node: '>= 6'}
@@ -1679,6 +1663,20 @@ packages:
function-bind: 1.1.1
dev: false

/hast-util-parse-selector@2.2.5:
resolution: {integrity: sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==}
dev: false

/hastscript@6.0.0:
resolution: {integrity: sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==}
dependencies:
'@types/hast': 2.3.4
comma-separated-tokens: 1.0.8
hast-util-parse-selector: 2.2.5
property-information: 5.6.0
space-separated-tokens: 1.1.5
dev: false

/http-signature@1.2.0:
resolution: {integrity: sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==}
engines: {node: '>=0.8', npm: '>=1.3.7'}
@@ -1740,6 +1738,17 @@ packages:
resolution: {integrity: sha512-pZ2xT+LOHckCatGQ3DcG/a+QuEqvoxqkiL7tvE8nn3uuu+f6i1TtpB5/FtWFbxUuVr5PZCx8KskuGatbJDXOWA==}
dev: false

/is-alphabetical@1.0.4:
resolution: {integrity: sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==}
dev: false

/is-alphanumerical@1.0.4:
resolution: {integrity: sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==}
dependencies:
is-alphabetical: 1.0.4
is-decimal: 1.0.4
dev: false

/is-array-buffer@3.0.2:
resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==}
dependencies:
@@ -1791,6 +1800,10 @@ packages:
has-tostringtag: 1.0.0
dev: false

/is-decimal@1.0.4:
resolution: {integrity: sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==}
dev: false

/is-docker@2.2.1:
resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==}
engines: {node: '>=8'}
@@ -1815,6 +1828,10 @@ packages:
is-extglob: 2.1.1
dev: false

/is-hexadecimal@1.0.4:
resolution: {integrity: sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==}
dev: false

/is-inside-container@1.0.0:
resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==}
engines: {node: '>=14.16'}
@@ -2346,6 +2363,17 @@ packages:
data-uri-to-buffer: 0.0.3
dev: false

/parse-entities@2.0.0:
resolution: {integrity: sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==}
dependencies:
character-entities: 1.2.4
character-entities-legacy: 1.1.4
character-reference-invalid: 1.1.4
is-alphanumerical: 1.0.4
is-decimal: 1.0.4
is-hexadecimal: 1.0.4
dev: false

/path-exists@4.0.0:
resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
engines: {node: '>=8'}
@@ -2487,6 +2515,11 @@ packages:
engines: {node: '>= 0.8.0'}
dev: false

/prismjs@1.27.0:
resolution: {integrity: sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==}
engines: {node: '>=6'}
dev: false

/prismjs@1.29.0:
resolution: {integrity: sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==}
engines: {node: '>=6'}
@@ -2500,6 +2533,12 @@ packages:
react-is: 16.13.1
dev: false

/property-information@5.6.0:
resolution: {integrity: sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==}
dependencies:
xtend: 4.0.2
dev: false

/psl@1.9.0:
resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==}
dev: false
@@ -2532,6 +2571,18 @@ packages:
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
dev: false

/react-refractor@2.1.7(react@18.2.0):
resolution: {integrity: sha512-avNxSSsnjYg+BKpO8LVCK14KRn5pLZ+8DInMiUEeZPL6hs0SN0zafl3mJIxavGQPKyihqbXqzq4CYNflJQjaaw==}
peerDependencies:
react: '>=15.0.0'
dependencies:
prop-types: 15.8.1
react: 18.2.0
refractor: 3.6.0
unist-util-filter: 2.0.3
unist-util-visit-parents: 3.1.1
dev: false

/react@18.2.0:
resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==}
engines: {node: '>=0.10.0'}
@@ -2552,6 +2603,14 @@ packages:
picomatch: 2.3.1
dev: false

/refractor@3.6.0:
resolution: {integrity: sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA==}
dependencies:
hastscript: 6.0.0
parse-entities: 2.0.0
prismjs: 1.27.0
dev: false

/regenerator-runtime@0.13.11:
resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==}
dev: false
@@ -2718,6 +2777,10 @@ packages:
engines: {node: '>=0.10.0'}
dev: false

/space-separated-tokens@1.1.5:
resolution: {integrity: sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==}
dev: false

/sshpk@1.17.0:
resolution: {integrity: sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==}
engines: {node: '>=0.10.0'}
@@ -3013,6 +3076,23 @@ packages:
resolution: {integrity: sha512-Gw+zz50YNKPDKXs+9d+aKAjVwpjNwqzvNpLigIruT4HA9lMZNdMqs9x07kKHB/L9WRzqp4+DlTU5s4wG2esdoA==}
dev: false

/unist-util-filter@2.0.3:
resolution: {integrity: sha512-8k6Jl/KLFqIRTHydJlHh6+uFgqYHq66pV75pZgr1JwfyFSjbWb12yfb0yitW/0TbHXjr9U4G9BQpOvMANB+ExA==}
dependencies:
unist-util-is: 4.1.0
dev: false

/unist-util-is@4.1.0:
resolution: {integrity: sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==}
dev: false

/unist-util-visit-parents@3.1.1:
resolution: {integrity: sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==}
dependencies:
'@types/unist': 2.0.6
unist-util-is: 4.1.0
dev: false

/untildify@4.0.0:
resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==}
engines: {node: '>=8'}
@@ -3105,6 +3185,11 @@ packages:
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
dev: false

/xtend@4.0.2:
resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
engines: {node: '>=0.4'}
dev: false

/yallist@4.0.0:
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
dev: false


+ 1
- 1
packages/web-kitchensink-reactnext/src/base/selectcontrol/index.ts 查看文件

@@ -1,5 +1,5 @@
export interface SelectOption {
label: string;
value?: string;
value?: string | number;
children?: SelectOption[];
}

+ 14
- 9
packages/web-kitchensink-reactnext/src/categories/blob/react/components/AudioFilePreview/index.tsx 查看文件

@@ -291,22 +291,27 @@ export const AudioFilePreview = React.forwardRef<AudioFilePreviewDerivedComponen
onChange={setSeek}
defaultValue="0"
step="any"
length="100%"
/>
</div>
<span className="tabular-nums font-bold">
{formatSecondsDurationConcise(durationDisplay)}
</span>
</div>
<Slider
ref={volumeRef}
max={1}
min={0}
onChange={adjustVolume}
step="any"
<div
className="flex-shrink-0 w-12"
defaultValue="1"
title="Volume"
/>
>
<Slider
ref={volumeRef}
max={1}
min={0}
onChange={adjustVolume}
step="any"
defaultValue="1"
title="Volume"
length="100%"
/>
</div>
</div>
)}
</div>


+ 19
- 17
packages/web-kitchensink-reactnext/src/categories/blob/react/components/TextFilePreview/index.tsx 查看文件

@@ -95,6 +95,22 @@ export const TextFilePreview = React.forwardRef<TextFilePreviewDerivedComponent,
children: formatFileSize(fileWithMetadata.size) || '(Loading)',
},
},
typeof fileWithMetadata.metadata?.lineCount === 'number'
&& typeof fileWithMetadata.metadata?.linesOfCode !== 'number'
&& {
key: 'Lines',
valueProps: {
children: `${formatNumeral(fileWithMetadata.metadata.lineCount)} line(s)`
},
},
typeof fileWithMetadata.metadata?.lineCount === 'number'
&& typeof fileWithMetadata.metadata?.linesOfCode === 'number'
&& {
key: 'Lines',
valueProps: {
children: `${formatNumeral(fileWithMetadata.metadata.lineCount)} line(s), ${formatNumeral(fileWithMetadata.metadata.linesOfCode)} loc`,
},
},
Array.isArray(fileWithMetadata.metadata?.languageMatches)
&& {
key: 'Language',
@@ -111,7 +127,9 @@ export const TextFilePreview = React.forwardRef<TextFilePreviewDerivedComponent,
{language.slice(1)}
</dt>
<dd className="tabular-nums">
({(probability * 100).toFixed(3)}%)
{(probability * 100).toFixed(3)}%
{' '}
<abbr title="probability">prob.</abbr>
</dd>
</div>
);
@@ -120,22 +138,6 @@ export const TextFilePreview = React.forwardRef<TextFilePreviewDerivedComponent,
),
},
},
typeof fileWithMetadata.metadata?.lineCount === 'number'
&& typeof fileWithMetadata.metadata?.linesOfCode !== 'number'
&& {
key: 'Lines',
valueProps: {
children: `${formatNumeral(fileWithMetadata.metadata.lineCount)} line(s)`
},
},
typeof fileWithMetadata.metadata?.lineCount === 'number'
&& typeof fileWithMetadata.metadata?.linesOfCode === 'number'
&& {
key: 'Lines',
valueProps: {
children: `${formatNumeral(fileWithMetadata.metadata.lineCount)} line(s), ${formatNumeral(fileWithMetadata.metadata.linesOfCode)} loc`,
},
},
]}
/>
</div>


+ 14
- 9
packages/web-kitchensink-reactnext/src/categories/blob/react/components/VideoFilePreview/index.tsx 查看文件

@@ -200,22 +200,27 @@ export const VideoFilePreview = React.forwardRef<VideoFilePreviewDerivedComponen
onChange={setSeek}
defaultValue="0"
step="any"
length="100%"
/>
</div>
<span className="tabular-nums font-bold">
{formatSecondsDurationConcise(durationDisplay)}
</span>
</div>
<Slider
ref={volumeRef}
max={1}
min={0}
onChange={adjustVolume}
step="any"
<div
className="flex-shrink-0 w-12"
defaultValue="1"
title="Volume"
/>
>
<Slider
ref={volumeRef}
max={1}
min={0}
onChange={adjustVolume}
step="any"
defaultValue="1"
title="Volume"
length="100%"
/>
</div>
</div>
)}
</div>


+ 189
- 19
packages/web-kitchensink-reactnext/src/categories/number/react/components/Slider/index.tsx 查看文件

@@ -1,37 +1,207 @@
import * as React from 'react';
import clsx from 'clsx';
import {slider} from './style.module.css';
import * as SelectControlBase from '@tesseract-design/web-base-selectcontrol';

type SliderDerivedComponent = HTMLInputElement;
type SliderOrientation = 'horizontal' | 'vertical';

export interface SliderProps extends Omit<React.HTMLProps<HTMLInputElement>, 'type'> {
interface RenderOptionsProps {
options: (number | SelectControlBase.SelectOption)[],
optionComponent?: React.ElementType,
optgroupComponent?: React.ElementType,
level?: number,
}

const RenderOptions: React.FC<RenderOptionsProps> = ({
options,
optionComponent: Option = 'option',
optgroupComponent: Optgroup = 'optgroup',
level = 0,
}: RenderOptionsProps) => (
<>
{
options.map((o) => {
if (typeof o === 'number') {
return (
<Option
key={`${o}:${o}`}
value={o}
/>
)
}

if (typeof o.value !== 'undefined') {
return (
<Option
key={`${o.label}:${o.value.toString()}`}
value={o.value}
label={o.label}
>
{o.label}
</Option>
);
}

if (typeof o.children !== 'undefined') {
if (level === 0) {
return (
<Optgroup
key={o.label}
label={o.label}
>
<RenderOptions
options={o.children}
optionComponent={Option}
optgroupComponent={Optgroup}
level={level + 1}
/>
</Optgroup>
);
}
return (
<React.Fragment
key={o.label}
>
<Option
disabled
>
{o.label}
</Option>
<RenderOptions
options={o.children}
optionComponent={Option}
optgroupComponent={Optgroup}
level={level + 1}
/>
</React.Fragment>
);
}

return null;
})
}
</>
);

type SliderDerivedElement = HTMLInputElement;

export interface SliderProps extends Omit<React.HTMLProps<HTMLInputElement>, 'type'> {
orient?: SliderOrientation;
tickMarks?: (number | SelectControlBase.SelectOption)[];
length?: React.CSSProperties['width'];
}

export const Slider = React.forwardRef<SliderDerivedComponent, SliderProps>(({
export const Slider = React.forwardRef<SliderDerivedElement, SliderProps>(({
className,
style,
tickMarks = [],
orient = 'horizontal',
length,
...etcProps
}, forwardedRef) => {
const [browser, setBrowser] = React.useState<string>();
React.useEffect(() => {
const isFirefox = typeof (window as unknown as Record<string, unknown>).InstallTrigger !== 'undefined';
if (isFirefox) {
setBrowser('firefox');
}
}, []);

const defaultRef = React.useRef<HTMLInputElement>(null);
const ref = forwardedRef ?? defaultRef;
const tickMarkId = React.useId();

React.useEffect(() => {
if (!(typeof ref === 'object' && ref.current)) {
return;
}

const {current: slider} = ref;
const isFirefox = browser === 'firefox';
if (isFirefox) {
slider.setAttribute('orient', orient);
slider.removeAttribute('data-orient');
}

return () => {
if (slider && isFirefox) {
slider.dataset.orient = slider.getAttribute(orient) ?? undefined;
slider.removeAttribute('orient');
}
};
}, [ref, orient, browser]);

React.useEffect(() => {
if (!(typeof ref === 'object' && ref.current)) {
return;
}

const {current: slider} = ref;
const isNotFirefox = browser !== 'firefox';
if (isNotFirefox && orient === 'vertical' && slider) {
const parent = slider.parentElement as HTMLElement;
const grandParent = parent.parentElement as HTMLElement;
const trueHeight = slider!.parentElement!.clientWidth;
const trueWidth = slider!.parentElement!.clientHeight;

grandParent.style.height = trueHeight + 'px';
grandParent.style.width = trueWidth + 'px';
}

return () => {
if (slider && isNotFirefox) {
}
};
}, [ref, orient, browser]);

const block = typeof length === 'string' && length.trim() === '100%';

return (
<div
className={clsx(
className,
)}
style={style}
>
<input
{...etcProps}
ref={forwardedRef}
type="range"
<>
{
tickMarks.length > 0
&& (
<datalist
id={tickMarkId}
>
<RenderOptions
options={tickMarks}
/>
</datalist>
)
}
<div
className={clsx(
slider,
'w-full h-full bg-inherit slider block text-primary ring-secondary/50 rounded-full',
'focus:text-secondary focus:outline-0 focus:ring-4',
'active:text-tertiary active:ring-tertiary/50',
block && orient !== 'vertical' && 'w-full',
!block && 'align-middle',
className,
orient !== 'vertical' && 'inline-block min-w-[16rem] min-h-[1rem]',
orient === 'vertical' && 'inline-block min-w-[1rem]',
//orient === 'vertical' && 'inline-block min-h-[16rem] min-w-[1rem]',
)}
/>
</div>
style={style}
>
<div
style={{
width: orient === 'vertical' ? (length ?? '16rem') : undefined,
position: 'relative',
}}
>
<input
{...etcProps}
ref={ref}
type="range"
data-orient={orient}
className={clsx(
slider,
'w-full h-full bg-inherit block text-primary ring-secondary/50 rounded-full',
'focus:text-secondary focus:outline-0 focus:ring-4',
'active:text-tertiary active:ring-tertiary/50',
)}
/>
</div>
</div>
</>
)
});



+ 55
- 18
packages/web-kitchensink-reactnext/src/categories/number/react/components/Slider/style.module.css 查看文件

@@ -7,19 +7,8 @@
color: rgb(var(--color-primary));
}

.slider::before {
border-radius: 9999px;
content: '';
display: block;
position: absolute;
background-color: currentColor;
opacity: 0.5;
width: 100%;
height: 50%;
top: 25%;
}

.slider::-webkit-slider-container {
width: 100%;
height: 100%;
overflow: hidden;
box-sizing: border-box;
@@ -27,7 +16,14 @@

.slider::-webkit-slider-runnable-track {
appearance: none;
height: 100%;
border-radius: 9999px;
content: '';
display: block;
position: absolute;
background-color: rgb(var(--color-primary) / 50%);
width: 100%;
height: 50%;
top: 25%;
}

.slider::-moz-range-track {
@@ -44,11 +40,13 @@
}

.slider::-webkit-slider-thumb {
margin-top: -0.25em;
width: 1em;
height: 200%;

border-radius: 9999px;
background-color: currentColor;
appearance: none;
width: 1em;
height: 100%;
aspect-ratio: 1 / 1;
z-index: 1;
position: relative;
@@ -56,16 +54,25 @@
}

.slider::-moz-range-thumb {
height: 100%;
outline: 0;
border: 0;

border-radius: 9999px;
background-color: currentColor;
appearance: none;
height: 100%;
aspect-ratio: 1 / 1;
z-index: 1;
position: relative;
box-shadow: -100000.5em 0 0 100000em rgb(var(--color-primary) / 50%);
outline: 0;
border: 0;
}

.slider:focus::-webkit-slider-runnable-track {
background-color: rgb(var(--color-secondary) / 50%);
}

.slider:active::-webkit-slider-runnable-track {
background-color: rgb(var(--color-tertiary) / 50%);
}

.slider:focus::-webkit-slider-thumb {
@@ -83,3 +90,33 @@
.slider:active::-moz-range-thumb {
box-shadow: -100000.5em 0 0 100000em rgb(var(--color-tertiary) / 50%);
}

.slider[orient='vertical'] {
width: 1em;
height: 16em;
}

.slider[orient='vertical']::-moz-range-track {
width: 50%;
height: 100%;
}

.slider[orient='vertical']::-moz-range-thumb {
width: 100%;
height: 1em;
box-shadow: 0 100000.5em 0 100000em rgb(var(--color-primary) / 50%);
}

.slider[orient='vertical']:focus::-moz-range-thumb {
box-shadow: 0 100000.5em 0 100000em rgb(var(--color-secondary) / 50%);
}

.slider[orient='vertical']:active::-moz-range-thumb {
box-shadow: 0 100000.5em 0 100000em rgb(var(--color-tertiary) / 50%);
}

.slider[data-orient='vertical'] {
rotate: -90deg;
translate: calc(-100% + 0.5em * 2);
transform-origin: calc(100% - 0.5em) 0.5em;
}

+ 17
- 5
packages/web-kitchensink-reactnext/src/packages/react-binary-data-canvas/index.tsx 查看文件

@@ -18,6 +18,7 @@ export const BinaryDataCanvas = React.forwardRef<BinaryDataCanvasDerivedElement,
byteClassName,
headers = false,
className,
style,
...etcProps
}, forwardedRef) => {
const bytesGrouped = arrayBuffer ? (Array.from(new Uint8Array(arrayBuffer)).slice(0, BYTES_PER_LINE * 20) as number[])
@@ -41,10 +42,17 @@ export const BinaryDataCanvas = React.forwardRef<BinaryDataCanvasDerivedElement,
) : [] as number[][];

return (
<div className={clsx(
'flex gap-2 leading-tight',
className,
)}>
<div
className={clsx(
className,
)}
style={{
...(style ?? {}),
display: 'flex',
gap: '0.5rem',
alignItems: 'flex-start',
}}
>
{headers && (
<pre
style={{
@@ -75,7 +83,11 @@ export const BinaryDataCanvas = React.forwardRef<BinaryDataCanvasDerivedElement,
<pre
{...etcProps}
ref={forwardedRef}
className="leading-tight"
style={{
padding: 0,
overflow: 'visible',
margin: 0,
}}
>
<code>
{headers && new Array(BYTES_PER_LINE).fill(0).map((_, i) => (


+ 19
- 80
packages/web-kitchensink-reactnext/src/packages/react-prism/index.tsx 查看文件

@@ -1,5 +1,5 @@
import * as React from 'react';
import PrismJs from 'prismjs';
import Refractor from 'react-refractor/all';
import clsx from 'clsx';

type PrismDerivedElement = HTMLPreElement;
@@ -24,52 +24,20 @@ export const Prism = React.forwardRef<PrismDerivedElement, PrismProps>(({
}, forwardedRef) => {
const [highlightedCode, setHighlightedCode] = React.useState<string>('');

React.useEffect(() => {
const loadHighlighter = async () => {
if (language !== 'plain') {
await import(`prismjs/components/prism-${language}`);
}

if (!code) {
setHighlightedCode('');
return;
}

if (!Number.isFinite(maxLineNumber)) {
setHighlightedCode(
PrismJs.highlight(
code,
PrismJs.languages[language],
language,
)
)
return;
}

setHighlightedCode(
PrismJs.highlight(
code,
PrismJs.languages[language],
language,
).split('\n').slice(0, maxLineNumber).join('\n')
);
}

void loadHighlighter();
}, [language, code, maxLineNumber]);

if (!code) {
return null;
}


return (
<div
className={clsx(
'flex gap-2 leading-tight',
'react-prism',
className,
)}
style={style}
style={{
...(style ?? {}),

}}
>
{lineNumbers && (
<pre
@@ -77,55 +45,26 @@ export const Prism = React.forwardRef<PrismDerivedElement, PrismProps>(({
padding: 0,
overflow: 'visible',
margin: 0,
lineHeight: 1.2,
textAlign: 'right',
}}
>
{new Array(maxLineNumber).fill(0).map((_, i) => (
<React.Fragment key={i}>
{i > 0 && '\n'}
<code
style={{
whiteSpace: 'nowrap',
}}
>
<code>
{new Array(maxLineNumber).fill(0).map((_, i) => (
<React.Fragment key={i}>
{i > 0 && '\n'}
{i + 1}
</code>
</React.Fragment>
))}
</React.Fragment>
))}
</code>
</pre>
)}
<pre
<Refractor
{...etcProps}
ref={forwardedRef}
>
{
language !== 'plain'
&& (
<code
className="prism"
dangerouslySetInnerHTML={{
__html: highlightedCode,
}}
style={{
tabSize,
}}
/>
)
}
{
language === 'plain'
&& (
<code
className="prism"
style={{
tabSize,
}}
>
{code}
</code>
)
}
</pre>
language={language}
value={code}
className="highlight"
/>
</div>
)
});


+ 36
- 222
packages/web-kitchensink-reactnext/src/pages/categories/number/index.tsx 查看文件

@@ -1,232 +1,46 @@
import * as React from 'react';
import { NextPage } from 'next';
import * as ReachSlider from '@reach/slider';
import '@reach/slider/styles.css';
import {delegateTriggerChangeEvent} from '../../../utils/event';
import * as SelectControlBase from '@tesseract-design/web-base-selectcontrol';

interface RenderOptionsProps {
options: (number | SelectControlBase.SelectOption)[],
optionComponent?: React.ElementType,
optgroupComponent?: React.ElementType,
level?: number,
}

export enum SliderOrientation {
HORIZONTAL = 'horizontal',
VERTICAL = 'vertical',
}

export interface SliderProps extends Omit<React.HTMLProps<HTMLInputElement>, 'type' | 'min' | 'max' | 'list'> {
enhanced?: boolean;
orient?: SliderOrientation;
min?: number;
max?: number;
block?: boolean;
tickMarks?: (number | SelectControlBase.SelectOption)[];
}

const RenderOptions: React.FC<RenderOptionsProps> = ({
options,
optionComponent: Option = 'option',
optgroupComponent: Optgroup = 'optgroup',
level = 0,
}: RenderOptionsProps) => (
<>
{
options.map((o) => {
if (typeof o === 'number') {
return (
<Option
key={`${o}:${o}`}
value={o}
/>
)
}

if (typeof o.value !== 'undefined') {
return (
<Option
key={`${o.label}:${o.value.toString()}`}
value={o.value}
label={o.label}
>
{o.label}
</Option>
);
}

if (typeof o.children !== 'undefined') {
if (level === 0) {
return (
<Optgroup
key={o.label}
label={o.label}
>
<RenderOptions
options={o.children}
optionComponent={Option}
optgroupComponent={Optgroup}
level={level + 1}
/>
</Optgroup>
);
}
return (
<React.Fragment
key={o.label}
>
<Option
disabled
>
{o.label}
</Option>
<RenderOptions
options={o.children}
optionComponent={Option}
optgroupComponent={Optgroup}
level={level + 1}
/>
</React.Fragment>
);
}

return null;
})
}
</>
);

export const Slider = React.forwardRef<HTMLInputElement, SliderProps>(({
enhanced = false,
orient = SliderOrientation.HORIZONTAL,
min = 0,
max = 100,
step = 'any',
block = false,
tickMarks = [],
onChange,
...etcProps
}, forwardedRef) => {
const [renderEnhanced, setRenderEnhanced] = React.useState(false);
const defaultRef = React.useRef<HTMLInputElement>(null);
const ref = forwardedRef ?? defaultRef;
const nonStandardProps: any = {
// Gecko (Firefox) fallback
orient,
}
const tickMarkId = React.useId();

React.useEffect(() => {
setRenderEnhanced(enhanced);
}, [enhanced]);

const handleEnhancedRangeChange = (newValue: number) => {
if (typeof ref === 'object' && ref.current) {
delegateTriggerChangeEvent(ref.current, newValue);
}
}

return (
<>
{
tickMarks.length > 0
&& (
<datalist
id={tickMarkId}
>
<RenderOptions
options={tickMarks}
/>
</datalist>
)
}
<div>
<input
{...etcProps}
{...nonStandardProps}
min={min}
max={max}
step={step ?? 'any'}
type="range"
className={`${renderEnhanced ? 'sr-only' : ''} ${block ? 'w-full' : ''}`}
ref={ref}
list={tickMarks.length > 0 ? tickMarkId : undefined}
onChange={onChange}
/>
{
renderEnhanced
&& (
<>
<ReachSlider.SliderInput
min={min}
max={max}
step={typeof step === 'number' ? step : Number.EPSILON}
orientation={orient === SliderOrientation.VERTICAL ? ReachSlider.SliderOrientation.Vertical : ReachSlider.SliderOrientation.Horizontal}
onChange={handleEnhancedRangeChange}
>
<ReachSlider.SliderTrack>
<ReachSlider.SliderRange />
<RenderOptions options={tickMarks} optionComponent={ReachSlider.SliderMarker} optgroupComponent={React.Fragment} />
<ReachSlider.SliderHandle />
</ReachSlider.SliderTrack>
</ReachSlider.SliderInput>
</>
)
}
</div>
</>
);
});

Slider.displayName = 'Slider';
import {Slider} from '@/categories/number/react';
import {Section, Subsection} from '@/components/Section';

const NumberPage: NextPage = () => {
return (
<main className="my-16 md:my-32">
<section>
<div className="container mx-auto px-4">
<h1>
Number
</h1>
<div>
<section>
<h2>
Spinner
</h2>
<div>
TODO

<input type="number" />
</div>
</section>
<section>
<h2>
Slider
</h2>
<div>
<Slider
min={-100}
max={100}
tickMarks={[{ label: 'low', value: 25, }, 50]}
enhanced
onChange={(e) => console.log(e.currentTarget.value)}
/>
</div>
</section>
<section>
<h2>
Matrix
</h2>
<div>
TODO
<input type="range" />
<input type="range" />
</div>
</section>
</div>
<Section title="Spinner">
<Subsection title="Default">
TODO

<input type="number" />
</Subsection>
</Section>
<Section title="Slider">
<Subsection title="Default">
<Slider
min={-100}
max={100}
tickMarks={[{ label: 'low', value: 25, }, 50]}
/>
</Subsection>
<Subsection title="Vertical">
<Slider
min={-100}
max={100}
tickMarks={[{ label: 'low', value: 25, }, 50]}
orient="vertical"
/>
A
</Subsection>
</Section>
<Section title="Matrix">
<h2>
Matrix
</h2>
<div>
TODO
<input type="range" />
<input type="range" />
</div>
</section>
</Section>
</main>
)
}


+ 19
- 13
packages/web-kitchensink-reactnext/src/styles/globals.css 查看文件

@@ -27,19 +27,25 @@
}
}

.prism .token.number { color: rgb(var(--color-code-number)); }
.prism .token.keyword { color: rgb(var(--color-code-keyword)); }
.prism .token.type { color: rgb(var(--color-code-type)); }
.prism .token.instance-attribute { color: rgb(var(--color-code-instance-attribute)); }
.prism .token.function { color: rgb(var(--color-code-function)); }
.prism .token.parameter { color: rgb(var(--color-code-parameter)); }
.prism .token.property { color: rgb(var(--color-code-property)); }
.prism .token.string { color: rgb(var(--color-code-string)); }
.prism .token.variable { color: rgb(var(--color-code-variable)); }
.prism .token.regexp { color: rgb(var(--color-code-regexp)); }
.prism .token.url { color: rgb(var(--color-code-url)); }
.prism .token.global { color: rgb(var(--color-code-global)); }
.prism .token.comment { opacity: 0.5; }
.react-prism {
display: flex;
gap: 0.5rem;
align-items: flex-start;
}

.react-prism .token.number { color: rgb(var(--color-code-number)); }
.react-prism .token.keyword { color: rgb(var(--color-code-keyword)); }
.react-prism .token.type { color: rgb(var(--color-code-type)); }
.react-prism .token.instance-attribute { color: rgb(var(--color-code-instance-attribute)); }
.react-prism .token.function { color: rgb(var(--color-code-function)); }
.react-prism .token.parameter { color: rgb(var(--color-code-parameter)); }
.react-prism .token.property { color: rgb(var(--color-code-property)); }
.react-prism .token.string { color: rgb(var(--color-code-string)); }
.react-prism .token.variable { color: rgb(var(--color-code-variable)); }
.react-prism .token.regexp { color: rgb(var(--color-code-regexp)); }
.react-prism .token.url { color: rgb(var(--color-code-url)); }
.react-prism .token.global { color: rgb(var(--color-code-global)); }
.react-prism .token.comment { opacity: 0.5; }

.binary-file-preview .x00 { color: rgb(var(--color-code-keyword)); }
.binary-file-preview .x10 { color: rgb(var(--color-code-global)); }


Loading…
取消
儲存