From 409b099adc8ee14bc76291cde20305b08ab40683 Mon Sep 17 00:00:00 2001 From: South Drifted Date: Wed, 17 Jan 2024 23:36:42 +0000 Subject: [PATCH] [add] Image, Ratio, Scroll Boundary & Tooltip components [optimize] update Upstream packages [remove] useless Component files --- package.json | 12 +++--- pnpm-lock.yaml | 42 ++++++++++---------- source/Image.tsx | 27 +++++++++++++ source/Nav.tsx | 11 ++---- source/Ratio.tsx | 22 +++++++++++ source/ScrollBoundary.tsx | 61 +++++++++++++++++++++++++++++ source/Tooltip.tsx | 76 +++++++++++++++++++++++++++++++++++++ source/index.ts | 4 ++ v1/Content/EdgeDetector.tsx | 66 -------------------------------- v1/Prompt/Tooltip/index.tsx | 63 ------------------------------ 10 files changed, 220 insertions(+), 164 deletions(-) create mode 100644 source/Image.tsx create mode 100644 source/Ratio.tsx create mode 100644 source/ScrollBoundary.tsx create mode 100644 source/Tooltip.tsx delete mode 100644 v1/Content/EdgeDetector.tsx delete mode 100644 v1/Prompt/Tooltip/index.tsx diff --git a/package.json b/package.json index e850231c..32189b76 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "boot-cell", - "version": "2.0.0-beta.2", + "version": "2.0.0-beta.3", "license": "LGPL-3.0", "author": "shiy2008@gmail.com", "description": "Web Components UI library based on WebCell v3, BootStrap v5, BootStrap Icon v1 & FontAwesome v6", @@ -26,10 +26,10 @@ "dependencies": { "@swc/helpers": "^0.5.3", "classnames": "^2.5.1", - "dom-renderer": "^2.0.5", + "dom-renderer": "^2.0.6", "mobx": "^6.12.0", "regenerator-runtime": "^0.14.1", - "web-cell": "^3.0.0-rc.6", + "web-cell": "^3.0.0-rc.7", "web-utility": "^4.1.3" }, "peerDependencies": { @@ -49,7 +49,7 @@ "@parcel/transformer-less": "~2.11.0", "@parcel/transformer-typescript-tsc": "^2.11.0", "@parcel/transformer-typescript-types": "~2.11.0", - "@peculiar/webcrypto": "^1.4.3", + "@peculiar/webcrypto": "^1.4.4", "@tech_query/snabbdom-looks-like": "^2.0.1", "@types/classnames": "^2.3.1", "@types/jest": "^29.5.11", @@ -66,11 +66,11 @@ "markdown-area-element": "^0.2.3", "open-cli": "^8.0.0", "parcel": "~2.11.0", - "prettier": "^3.1.1", + "prettier": "^3.2.4", "ts-jest": "^29.1.1", "ts-node": "^10.9.2", "typedoc": "^0.25.7", - "typedoc-plugin-mdn-links": "^3.1.11", + "typedoc-plugin-mdn-links": "^3.1.12", "typescript": "~5.3.3" }, "scripts": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 93c35607..4bfbdc8b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,8 +12,8 @@ dependencies: specifier: ^2.5.1 version: 2.5.1 dom-renderer: - specifier: ^2.0.5 - version: 2.0.5(typescript@5.3.3) + specifier: ^2.0.6 + version: 2.0.6(typescript@5.3.3) mobx: specifier: ^6.12.0 version: 6.12.0 @@ -21,8 +21,8 @@ dependencies: specifier: ^0.14.1 version: 0.14.1 web-cell: - specifier: ^3.0.0-rc.6 - version: 3.0.0-rc.6(element-internals-polyfill@1.3.10)(typescript@5.3.3) + specifier: ^3.0.0-rc.7 + version: 3.0.0-rc.7(element-internals-polyfill@1.3.10)(typescript@5.3.3) web-utility: specifier: ^4.1.3 version: 4.1.3(typescript@5.3.3) @@ -50,8 +50,8 @@ devDependencies: specifier: ~2.11.0 version: 2.11.0(typescript@5.3.3) '@peculiar/webcrypto': - specifier: ^1.4.3 - version: 1.4.3 + specifier: ^1.4.4 + version: 1.4.4 '@tech_query/snabbdom-looks-like': specifier: ^2.0.1 version: 2.0.1 @@ -101,8 +101,8 @@ devDependencies: specifier: ~2.11.0 version: 2.11.0(@swc/helpers@0.5.3)(typescript@5.3.3) prettier: - specifier: ^3.1.1 - version: 3.1.1 + specifier: ^3.2.4 + version: 3.2.4 ts-jest: specifier: ^29.1.1 version: 29.1.1(@jest/types@29.6.3)(jest@29.7.0)(typescript@5.3.3) @@ -113,8 +113,8 @@ devDependencies: specifier: ^0.25.7 version: 0.25.7(typescript@5.3.3) typedoc-plugin-mdn-links: - specifier: ^3.1.11 - version: 3.1.11(typedoc@0.25.7) + specifier: ^3.1.12 + version: 3.1.12(typedoc@0.25.7) typescript: specifier: ~5.3.3 version: 5.3.3 @@ -1742,8 +1742,8 @@ packages: tslib: 2.6.2 dev: true - /@peculiar/webcrypto@1.4.3: - resolution: {integrity: sha512-VtaY4spKTdN5LjJ04im/d/joXuvLbQdgy5Z4DXF4MFZhQ+MTrejbNMkfZBp1Bs3O5+bFqnJgyGdPuZQflvIa5A==} + /@peculiar/webcrypto@1.4.4: + resolution: {integrity: sha512-VETlZgJqOP3OLRC7AcEYfb6/u05evqsW0Vgs9DyCBATp3FSx7D30Z8ALuDJHsmXCsMblfyTwvB9PLR6IfdlRhg==} engines: {node: '>=10.12.0'} dependencies: '@peculiar/asn1-schema': 2.3.8 @@ -2601,8 +2601,8 @@ packages: engines: {node: '>=0.3.1'} dev: true - /dom-renderer@2.0.5(typescript@5.3.3): - resolution: {integrity: sha512-9N5Da1qcv2y2i8UV77aJkHOHScWhmmiJIuWaiqgmIcPRn15IhQLbagJIt5Dhg4x08rf6bT9WmOccPKHMAPJDDw==} + /dom-renderer@2.0.6(typescript@5.3.3): + resolution: {integrity: sha512-gsf0N9EY1ambqrg8/eOeGwbifqxyJ9vQN8zWDdmj88dYsvwxv2kSV34T6Nt8fu0kYrwUsYadb4tdFjTrPRM7vw==} dependencies: tslib: 2.6.2 web-utility: 4.1.3(typescript@5.3.3) @@ -4315,8 +4315,8 @@ packages: posthtml-render: 3.0.0 dev: true - /prettier@3.1.1: - resolution: {integrity: sha512-22UbSzg8luF4UuZtzgiUOfcGM8s4tjBv6dJRT7j275NXsy2jb4aJa4NNveul5x4eqlF1wuhuR2RElK71RvmVaw==} + /prettier@3.2.4: + resolution: {integrity: sha512-FWu1oLHKCrtpO1ypU6J0SbK2d9Ckwysq6bHj/uaCP26DxrPpppCLQRGVuqAxSTvhF00AcvDRyYrLNW7ocBhFFQ==} engines: {node: '>=14'} hasBin: true dev: true @@ -4865,8 +4865,8 @@ packages: engines: {node: '>=14.16'} dev: true - /typedoc-plugin-mdn-links@3.1.11(typedoc@0.25.7): - resolution: {integrity: sha512-WmEt+FD6HKXCkcbQEmdVKtkEEJb9SLmUnGnKwKM9U5grocy9TOUQ1GmO2cXnzMBQ2i/o/wF8LK4JQf5Vch3DKg==} + /typedoc-plugin-mdn-links@3.1.12(typedoc@0.25.7): + resolution: {integrity: sha512-B6GLXAq2kL7crem0uJYAN7uMmbBZdf+znUanwk/u6gQQFKveUSzCZrtO9pb0ZIe2uCv1T60XDfcO+bTm7R18aw==} peerDependencies: typedoc: '>= 0.23.14 || 0.24.x || 0.25.x' dependencies: @@ -4968,8 +4968,8 @@ packages: - typescript dev: true - /web-cell@3.0.0-rc.6(element-internals-polyfill@1.3.10)(typescript@5.3.3): - resolution: {integrity: sha512-MYjeOVyPmfDiL/bOC7J37GMysaVwUR2TSB6k0rbwPtkP9LqHreRwdTlXCcEWowMWqx4lonMyyt/JShpFuDJ/Nw==} + /web-cell@3.0.0-rc.7(element-internals-polyfill@1.3.10)(typescript@5.3.3): + resolution: {integrity: sha512-c4+nelL24NYDEtQMsr5r1ftSO6Jg9KCQJAxHYttBSdiZwrAybhVV/qLEsrI+ax3OLmHKxy7WjBWJVYopcaG54A==} peerDependencies: '@webcomponents/webcomponentsjs': ^2.8 core-js: ^3 @@ -4977,7 +4977,7 @@ packages: jsdom: '>=21' dependencies: '@swc/helpers': 0.5.3 - dom-renderer: 2.0.5(typescript@5.3.3) + dom-renderer: 2.0.6(typescript@5.3.3) element-internals-polyfill: 1.3.10 mobx: 6.12.0 regenerator-runtime: 0.14.1 diff --git a/source/Image.tsx b/source/Image.tsx new file mode 100644 index 00000000..0491867c --- /dev/null +++ b/source/Image.tsx @@ -0,0 +1,27 @@ +import classNames from 'classnames'; +import { FC, WebCellProps } from 'web-cell'; + +export type ImageProps = WebCellProps & + Partial< + Record<'fluid' | 'rounded' | 'roundedCircle' | 'thumbnail', boolean> + >; + +export const Image: FC = ({ + className, + fluid, + rounded, + roundedCircle, + thumbnail, + ...props +}) => ( + +); diff --git a/source/Nav.tsx b/source/Nav.tsx index c7495c3a..bd5c1a4f 100644 --- a/source/Nav.tsx +++ b/source/Nav.tsx @@ -13,14 +13,9 @@ export const NavLink: FC = ({ children, ...props }) => ( -
  • - - {children} - -
  • + + {children} + ); export interface Nav extends WebCell {} diff --git a/source/Ratio.tsx b/source/Ratio.tsx new file mode 100644 index 00000000..fc0cd260 --- /dev/null +++ b/source/Ratio.tsx @@ -0,0 +1,22 @@ +import classNames from 'classnames'; +import { FC, WebCellProps } from 'web-cell'; + +export interface RatioProps extends WebCellProps { + aspectRatio?: number | '1x1' | '4x3' | '16x9' | '21x9'; +} + +export const Ratio: FC = ({ aspectRatio = '1x1', children }) => ( +
    + {children} +
    +); diff --git a/source/ScrollBoundary.tsx b/source/ScrollBoundary.tsx new file mode 100644 index 00000000..cdb083a3 --- /dev/null +++ b/source/ScrollBoundary.tsx @@ -0,0 +1,61 @@ +import classNames from 'classnames'; +import { JsxChildren } from 'dom-renderer'; +import { FC, WebCellProps } from 'web-cell'; + +export type EdgePosition = 'top' | 'bottom' | 'left' | 'right'; + +export type TouchHandler = (edge: EdgePosition) => any; + +export interface ScrollBoundaryProps + extends WebCellProps, + Partial> { + onTouch: TouchHandler; +} + +function touch(edge: EdgePosition, onTouch: TouchHandler) { + return (node: HTMLElement | null) => + node && + new IntersectionObserver( + ([{ isIntersecting }]) => isIntersecting && onTouch(edge) + ).observe(node); +} + +export const ScrollBoundary: FC = ({ + className, + onTouch, + top, + left, + right, + bottom, + children +}) => ( +
    +
    + {top} +
    +
    + {left} +
    + + {children} + +
    + {right} +
    +
    + {bottom} +
    +
    +); diff --git a/source/Tooltip.tsx b/source/Tooltip.tsx new file mode 100644 index 00000000..c3c74b0b --- /dev/null +++ b/source/Tooltip.tsx @@ -0,0 +1,76 @@ +import { JsxChildren } from 'dom-renderer'; +import { observable } from 'mobx'; +import { + FC, + WebCell, + WebCellProps, + attribute, + component, + observer +} from 'web-cell'; + +export const Tooltip: FC = ({ + className = '', + children, + ...props +}) => ( +
    +
    +
    {children}
    +
    +); + +export interface TooltipBoxProps extends WebCellProps { + content: JsxChildren; +} + +export interface TooltipBox extends WebCell {} + +@component({ + tagName: 'tooltip-box', + mode: 'open' +}) +@observer +export class TooltipBox extends HTMLElement implements WebCell { + declare props: TooltipBoxProps; + + content: JsxChildren; + + @attribute + @observable + accessor show = false; + + connectedCallback() { + this.style.display = 'inline-block'; + + this.addEventListener('mouseenter', this.handleToggle); + this.addEventListener('mouseleave', this.handleToggle); + } + + disconnectedCallback() { + this.removeEventListener('mouseenter', this.handleToggle); + this.removeEventListener('mouseleave', this.handleToggle); + } + + handleToggle = () => (this.show = !this.show); + + render() { + const { content, show } = this; + + return ( + <> + + + + {show && {content}} + + ); + } +} diff --git a/source/index.ts b/source/index.ts index e94eacd9..3ca636d3 100644 --- a/source/index.ts +++ b/source/index.ts @@ -1,9 +1,13 @@ export * from './type'; +export * from './Ratio'; export * from './Grid'; export * from './Table'; +export * from './ScrollBoundary'; export * from './Form'; export * from './Button'; export * from './Icon'; +export * from './Image'; +export * from './Tooltip'; export * from './Dropdown'; export * from './Nav'; export * from './Navbar'; diff --git a/v1/Content/EdgeDetector.tsx b/v1/Content/EdgeDetector.tsx deleted file mode 100644 index 266042ee..00000000 --- a/v1/Content/EdgeDetector.tsx +++ /dev/null @@ -1,66 +0,0 @@ -import { WebCellProps, component, mixin, createCell, Fragment } from 'web-cell'; - -type EdgeSide = 'top' | 'bottom' | 'left' | 'right'; - -export type EdgeEvent = CustomEvent; - -declare global { - interface HTMLElementEventMap { - touchedge: EdgeEvent; - } -} - -export interface EdgeDetectorProps extends WebCellProps { - onTouchEdge?(event: EdgeEvent): any; -} - -@component({ - tagName: 'edge-detector', - style: { - main: { - position: 'relative' - }, - '.left, .right': { - position: 'absolute', - top: '0', - height: '100%' - }, - '.left': { - left: '0' - }, - '.right': { - right: '0' - } - } -}) -export class EdgeDetector extends mixin() { - watch(side: EdgeSide, node: HTMLElement) { - new IntersectionObserver(([{ isIntersecting }]) => { - if (isIntersecting) this.emit('touchedge', side); - }).observe(node); - } - - render() { - return ( - <> -
    - -
    -
    -
    - -
    - - - -
    - -
    -
    -
    - -
    - - ); - } -} diff --git a/v1/Prompt/Tooltip/index.tsx b/v1/Prompt/Tooltip/index.tsx deleted file mode 100644 index fdfbb0f2..00000000 --- a/v1/Prompt/Tooltip/index.tsx +++ /dev/null @@ -1,63 +0,0 @@ -import { - WebCellProps, - VNodeChildElement, - component, - mixin, - createCell, - Fragment, - watch, - attribute -} from 'web-cell'; -import { transitIn, transitOut } from 'web-utility/source/animation'; - -import { Position } from '../../utility/constant'; - -import './index.less'; - -export interface TooltipProps extends WebCellProps { - text: VNodeChildElement; - position?: keyof typeof Position; -} - -@component({ - tagName: 'tooltip-box', - renderTarget: 'children' -}) -export class TooltipBox extends mixin() { - @watch - text = ''; - - @attribute - @watch - position = 'top'; - - connectedCallback() { - this.style.display = 'inline-block'; - this.style.position = 'relative'; - - this.addEventListener('mouseenter', () => - transitIn(this.lastElementChild as HTMLElement, 'show') - ); - this.addEventListener('mouseleave', () => - transitOut(this.lastElementChild as HTMLElement, 'show') - ); - - super.connectedCallback(); - } - - render({ defaultSlot, text, position }: TooltipProps) { - return ( - <> - {defaultSlot} - -
    -
    -
    {text}
    -
    - - ); - } -}