From 165741cc5457ea7cde8ec557f149ed27985d1680 Mon Sep 17 00:00:00 2001 From: yutent Date: Mon, 6 Mar 2023 12:25:54 +0800 Subject: [PATCH] init --- .gitignore | 20 +++++++ .prettierrc.yaml | 10 ++++ LICENSE | 21 +++++++ Readme.md | 93 ++++++++++++++++++++++++++++++ package.json | 26 +++++++++ src/constants.js | 18 ++++++ src/index.js | 144 +++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 332 insertions(+) create mode 100644 .gitignore create mode 100644 .prettierrc.yaml create mode 100644 LICENSE create mode 100644 Readme.md create mode 100644 package.json create mode 100644 src/constants.js create mode 100644 src/index.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cec61b0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,20 @@ +*.min.js +*.min.css +.httpserver +index.html +test.js +.vscode +node_modules/ +dist/ +*.sublime-project +*.sublime-workspace +package-lock.json + + +._* + +.Spotlight-V100 +.Trashes +.DS_Store +.AppleDouble +.LSOverride \ No newline at end of file diff --git a/.prettierrc.yaml b/.prettierrc.yaml new file mode 100644 index 0000000..b007fb1 --- /dev/null +++ b/.prettierrc.yaml @@ -0,0 +1,10 @@ +jsxBracketSameLine: true +jsxSingleQuote: true +semi: false +singleQuote: true +printWidth: 80 +useTabs: false +tabWidth: 2 +trailingComma: none +bracketSpacing: true +arrowParens: avoid \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..ab60297 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Readme.md b/Readme.md new file mode 100644 index 0000000..8f1b84c --- /dev/null +++ b/Readme.md @@ -0,0 +1,93 @@ +## 9号UI组件库的核心 + + +```js +import { css, html, Component } from '//jscdn.ink/@ninejs/core/latest/index.js' + +class Hello extends Component { + + static props = { + count: { + type: Number, + default: 0 + } + } + + static styles = css` + button { color: #09f; } + span { color: #f30; } + ` + + render(){ + return html` +
+ +
+
所有点击数为: ${this.count}
+ ` + } + + increase(){ + this.count++ + } + +} + +customElements.define('wc-hello', Hello) + + +/* + + + + +*/ + +``` + +若需要支持 scss, 则需要使用构建工具,预处理。 + +```js +import { css, html, Component } from '@ninejs/core' + +@customElement('wc-hello') +class Hello extends Component { + + static props = { + count: { + type: Number, + default: 0 + } + } + + // 这个scss会被解析进来 + @extendStyle('hello.scss') + static styles + + render(){ + return html` +
+ +
+
所有点击数为: ${this.count}
+ ` + } + + increase(){ + this.count++ + } + +} + +// 这个可以省略 +// customElements.define('wc-hello', Hello) + + +/* + + + + +*/ + +``` \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..224c930 --- /dev/null +++ b/package.json @@ -0,0 +1,26 @@ +{ + "name": "@ninejs/core", + "version": "0.0.1", + "type": "module", + "description": "", + "main": "dist/index.js", + "files": [ + "dist/*" + ], + "scripts": {}, + "repository": { + "type": "git", + "url": "git+https://github.com/bytedo/nine-core.git" + }, + "keywords": [ + "nine.", + "ninejs", + "nine-ui", + "nine-core" + ], + "devDependencies": { + "esbuild": "^0.17.11" + }, + "author": "yutent", + "license": "MIT" +} diff --git a/src/constants.js b/src/constants.js new file mode 100644 index 0000000..82365dd --- /dev/null +++ b/src/constants.js @@ -0,0 +1,18 @@ +/** + * {} + * @author yutent + * @date 2023/03/06 12:08:35 + */ + +export const finalize = Symbol('finalize') +export const RESET_CSS_STYLE = css` + * { + box-sizing: border-box; + margin: 0; + padding: 0; + } + ::before, + ::after { + box-sizing: border-box; + } +` diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..129ce7a --- /dev/null +++ b/src/index.js @@ -0,0 +1,144 @@ +/** + * {全新的组件核心库} + * @author yutent + * @date 2023/03/03 11:21:44 + */ + +import { finalize, RESET_CSS_STYLE } from './constants.js' + +export function css(strs, ...args) { + let output = ` + + ` + let tmp = Array.from(strs) + while (tmp.length) { + output += tmp.shift() + (args.shift() || '') + } + + if (args.length) { + output += args.join(' ') + } + return output +} + +export function html(strs, ...args) { + let output = '' + let tmp = Array.from(strs) + // console.log(tmp, args) + + while (tmp.length) { + let _ = args.shift() + switch (typeof _) { + case 'function': + console.log([_], _.name) + _ = _.name + break + case 'object': + if (Array.isArray(_)) { + _ = _.join('') + } + break + } + output += tmp.shift() + (_ === void 0 ? '' : _) + } + + if (args.length) { + output += args.join(' ') + } + return output +} + +function getTemplate(html) { + let template = document.createElement('template') + template.innerHTML = html + return template.content.cloneNode(true) +} + +function adoptStyles(root, styles = '') { + let sheet = new CSSStyleSheet() + if (typeof styles === 'string') { + styles = [styles] + } else { + styles = styles.flat(Infinity) + } + styles = (RESET_CSS_STYLE + styles.join(' ')).trim() + sheet.replaceSync(styles) + root.adoptedStyleSheets.push(sheet) +} + +function render(root, html) { + root.appendChild(getTemplate(html)) +} + +export class Component extends HTMLElement { + static get observedAttributes() { + this[finalize]() + + let list = [] + this.elemProps.forEach((it, prop) => { + list.push(prop) + }) + return list + } + + constructor() { + super() + this.created && this.created() + } + + static [finalize]() { + if (this.finalized) { + return + } + + this.finalized = true + + this.elemProps = new Map() + + for (let k in this.props) { + let prop = Symbol(k) + let options = this.props[k] + this.elemProps.set(k, prop) + Object.defineProperty(this.prototype, k, { + get() { + return this[prop] || options.default + }, + set(val) { + this[prop] = val + }, + enumerable: false + }) + } + } + + render() { + return '' + } + + connectedCallback() { + Object.defineProperty(this, 'root', { + value: this.shadowRoot || this.attachShadow({ mode: 'open' }), + enumerable: false + }) + + adoptStyles(this.root, this.constructor.styles) + + render(this.root, this.render()) + + this.mounted && this.mounted() + } + + disconnectedCallback() { + console.log('>>>>') + } + + attributeChangedCallback(name, old, val) { + if (old === val) { + return + } + } + + adoptedCallback() { + // + } +}