diff --git a/example/darkmode/controller/controller.go b/example/darkmode/controller/controller.go new file mode 100644 index 00000000..5c48389d --- /dev/null +++ b/example/darkmode/controller/controller.go @@ -0,0 +1,18 @@ +package controller + +import ( + "net/http" +) + +type Controller struct { + Writer http.ResponseWriter +} + +func (c *Controller) Index() {} + +func (c *Controller) Create(theme string) { + http.SetCookie(c.Writer, &http.Cookie{ + Name: "theme", + Value: theme, + }) +} diff --git a/example/darkmode/gitignore b/example/darkmode/gitignore new file mode 100644 index 00000000..57e45f1f --- /dev/null +++ b/example/darkmode/gitignore @@ -0,0 +1,2 @@ +node_modules/ +bud/ diff --git a/example/darkmode/go.mod b/example/darkmode/go.mod new file mode 100644 index 00000000..f87c3c65 --- /dev/null +++ b/example/darkmode/go.mod @@ -0,0 +1,11 @@ +module github.com/livebud/bud/example/darkmode + +go 1.18 + +require ( + github.com/livebud/bud v0.0.0 +) + +replace ( + github.com/livebud/bud => /Users/m/dev/src/github.com/livebud/bud +) diff --git a/example/darkmode/go.sum b/example/darkmode/go.sum new file mode 100644 index 00000000..3f173d94 --- /dev/null +++ b/example/darkmode/go.sum @@ -0,0 +1,36 @@ +github.com/PuerkitoBio/goquery v1.8.0 h1:PJTF7AmFCFKk1N6V6jmKfrNH9tV5pNE6lZMkG0gta/U= +github.com/ajg/form v1.5.2-0.20200323032839-9aeb3cf462e1 h1:8Qzi+0Uch1VJvdrOhJ8U8FqoPLbUdETPgMqGJ6DSMSQ= +github.com/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x004T2c= +github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= +github.com/bep/debounce v1.2.1 h1:v67fRdBA9UQu2NhLFXrSg0Brw7CexQekrBwDMM8bzeY= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/evanw/esbuild v0.14.11 h1:bw50N4v70Dqf/B6Wn+3BM6BVttz4A6tHn8m8Ydj9vxk= +github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= +github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI= +github.com/gedex/inflector v0.0.0-20170307190818-16278e9db813 h1:Uc+IZ7gYqAf/rSGFplbWBSHaGolEQlNLgMgSE3ccnIQ= +github.com/gitchander/permutation v0.0.0-20201214100618-1f3e7285f953 h1:+rJDfq6waeB1BncyEfuFL1N3U7t3aahrAjPqcKLpMys= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/lithammer/dedent v1.1.0 h1:VNzHMVCBNG1j0fh3OrsFRkVUwStdDArbgBWoPAffktY= +github.com/matthewmueller/diff v0.0.0-20220104030700-cb2fe910d90c h1:yjGBNrCIE7IghJAwrFcyDzwzwJKf0oRPeOHx60wfkmA= +github.com/matthewmueller/gotext v0.0.0-20210424201144-265ed61725ac h1:SjopLdUF96kdJU8ynYmGVHoJmngpwFHRvR5p2plBXG4= +github.com/matthewmueller/text v0.0.0-20210424201111-ec1e4af8dfe8 h1:XTmVlF7P9bpSNkLFlxpNlhig0kaVJ5mO4D3yK2CYjmM= +github.com/otiai10/copy v1.7.0 h1:hVoPiN+t+7d2nzzwMiDHPSOogsWAStewq3TwU05+clE= +github.com/pointlander/compress v1.1.1-0.20190518213731-ff44bd196cc3 h1:hUmXhbljNFtrH5hzV9kiRoddZ5nfPTq3K0Sb2hYYiqE= +github.com/pointlander/jetset v1.0.1-0.20190518214125-eee7eff80bd4 h1:RHHRCZeaNyBXdYPMjZNH8/XHDBH38TZzw8izrW7dmBE= +github.com/pointlander/peg v1.0.1 h1:mgA/GQE8TeS9MdkU6Xn6iEzBmQUQCNuWD7rHCK6Mjs0= +github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg= +github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 h1:OkMGxebDjyw0ULyrTYWeN0UNCCkmCWfjPnIA2W6oviI= +github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= +github.com/timewasted/go-accept-headers v0.0.0-20130320203746-c78f304b1b09 h1:QVxbx5l/0pzciWYOynixQMtUhPYC3YKD6EcUlOsgGqw= +github.com/xlab/treeprint v1.1.0 h1:G/1DjNkPpfZCFt9CSh6b5/nY4VimlbHF3Rh4obvtzDk= +go.kuoruan.net/v8go-polyfills v0.5.0 h1:wd2WxsFIXWK/FcrpITw6BOo8Rn24xMmd4qoHofgg8hc= +golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f h1:OfiFi4JbukWwe3lzw+xunroH1mnC1e2Gy5cxNJApiSY= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= +golang.org/x/tools v0.1.9 h1:j9KsMiaP1c3B0OTQGth0/k+miLGTgLsAFUCrF2vLcF8= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= +rogchap.com/v8go v0.7.0 h1:kgjbiO4zE5itA962ze6Hqmbs4HgZbGzmueCXsZtremg= +src.techknowlogick.com/xgo v1.4.1-0.20220413212431-091a0a22b814 h1:/oIyHjKnlyQ3yFzxq7uin83l6h0sHXT7Z+9TpP9wr8s= diff --git a/example/darkmode/module/cookie/index.ts b/example/darkmode/module/cookie/index.ts new file mode 100644 index 00000000..fbf77623 --- /dev/null +++ b/example/darkmode/module/cookie/index.ts @@ -0,0 +1,125 @@ +/** + * Export all by default + * Based on: https://github.com/component/cookie + */ + +export default { all, get, set } + +/** + * Cookie type + */ + +type Cookies = { + [cookie: string]: string +} + +/** + * Set options + */ + +type Options = { + maxage?: number + expires?: Date + domain?: string + path?: string + secure?: boolean +} + +/** + * Set cookie `name` to `value`. + */ + +function set(name: string, value: string | null, options?: Options) { + options = options || {} + var str = encode(name) + '=' + encode(String(value)) + + if (null == value) { + options.maxage = -1 + } + + if (options.maxage) { + options.expires = new Date(+new Date() + options.maxage) + } + + if (options.path) str += '; path=' + options.path + if (options.domain) str += '; domain=' + options.domain + if (options.expires) str += '; expires=' + options.expires.toUTCString() + if (options.secure) str += '; secure' + + document.cookie = str +} + +/** + * Return all cookies. + * + * This is isomorphic and may be called + * from the server-side though it will + * return nothing. + */ + +function all(): Cookies { + var str + try { + str = document.cookie + } catch (err) { + console.log(err) + return {} + } + return parse(str) +} + +/** + * Get cookie `name`. + */ + +function get(name: string): string | undefined { + return all()[name] +} + +/** + * Parse cookie `str`. + */ + +function parse(str: string): Cookies { + var obj = {} + var pairs = str.split(/ *; */) + for (var i = 0; i < pairs.length; ++i) { + var pair = pairs[i] + var eqidx = pair.indexOf('=') + if (eqidx === -1) { + eqidx = pair.length + } + var name = decode(pair.substr(0, eqidx)) + // +1 because we don't want the = + var value = decode(pair.substr(eqidx + 1)) + if (!name || !value) { + continue + } + obj[name] = value + } + return obj +} + +/** + * Encode. + */ + +function encode(value: string): string | undefined { + try { + return encodeURIComponent(value) + } catch (e) { + return + } +} + +/** + * Decode. + */ + +function decode(value: string): string | undefined { + try { + return decodeURIComponent(value) + } catch (e) { + return + } +} \ No newline at end of file diff --git a/example/darkmode/package-lock.json b/example/darkmode/package-lock.json new file mode 100644 index 00000000..49312ca4 --- /dev/null +++ b/example/darkmode/package-lock.json @@ -0,0 +1,134 @@ +{ + "name": "darkmode", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "darkmode", + "dependencies": { + "livebud": "latest", + "svelte": "3.47.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/livebud": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/livebud/-/livebud-0.1.11.tgz", + "integrity": "sha512-dIPUqtjrGf82RCF/FG3+vjBfDxi51yKcaTfykFO/t3q7Fq+uEIf3laMyFhRIAQPwJa+K4uBd0+s9swcokvreQg==", + "dependencies": { + "react": "18.0.0", + "react-dom": "18.0.0", + "svelte": "3.47.0" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/react": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.0.0.tgz", + "integrity": "sha512-x+VL6wbT4JRVPm7EGxXhZ8w8LTROaxPXOqhlGyVSrv0sB1jkyFGgXxJ8LVoPRLvPR6/CIZGFmfzqUa2NYeMr2A==", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.0.0.tgz", + "integrity": "sha512-XqX7uzmFo0pUceWFCt7Gff6IyIMzFUn7QMZrbrQfGxtaxXZIcGQzoNpRLE3fQLnS4XzLLPMZX2T9TRcSrasicw==", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.21.0" + }, + "peerDependencies": { + "react": "^18.0.0" + } + }, + "node_modules/scheduler": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.21.0.tgz", + "integrity": "sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ==", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/svelte": { + "version": "3.47.0", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.47.0.tgz", + "integrity": "sha512-4JaJp3HEoTCGARRWZQIZDUanhYv0iyoHikklVHVLH9xFE9db22g4TDv7CPeNA8HD1JgjXI1vlhR1JZvvhaTu2Q==", + "engines": { + "node": ">= 8" + } + } + }, + "dependencies": { + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "livebud": { + "version": "0.1.11", + "resolved": "https://registry.npmjs.org/livebud/-/livebud-0.1.11.tgz", + "integrity": "sha512-dIPUqtjrGf82RCF/FG3+vjBfDxi51yKcaTfykFO/t3q7Fq+uEIf3laMyFhRIAQPwJa+K4uBd0+s9swcokvreQg==", + "requires": { + "react": "18.0.0", + "react-dom": "18.0.0", + "svelte": "3.47.0" + } + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "react": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.0.0.tgz", + "integrity": "sha512-x+VL6wbT4JRVPm7EGxXhZ8w8LTROaxPXOqhlGyVSrv0sB1jkyFGgXxJ8LVoPRLvPR6/CIZGFmfzqUa2NYeMr2A==", + "requires": { + "loose-envify": "^1.1.0" + } + }, + "react-dom": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.0.0.tgz", + "integrity": "sha512-XqX7uzmFo0pUceWFCt7Gff6IyIMzFUn7QMZrbrQfGxtaxXZIcGQzoNpRLE3fQLnS4XzLLPMZX2T9TRcSrasicw==", + "requires": { + "loose-envify": "^1.1.0", + "scheduler": "^0.21.0" + } + }, + "scheduler": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.21.0.tgz", + "integrity": "sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ==", + "requires": { + "loose-envify": "^1.1.0" + } + }, + "svelte": { + "version": "3.47.0", + "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.47.0.tgz", + "integrity": "sha512-4JaJp3HEoTCGARRWZQIZDUanhYv0iyoHikklVHVLH9xFE9db22g4TDv7CPeNA8HD1JgjXI1vlhR1JZvvhaTu2Q==" + } + } +} diff --git a/example/darkmode/package.json b/example/darkmode/package.json new file mode 100644 index 00000000..1ed8752f --- /dev/null +++ b/example/darkmode/package.json @@ -0,0 +1,8 @@ +{ + "name": "darkmode", + "private": true, + "dependencies": { + "livebud": "latest", + "svelte": "3.47.0" + } +} \ No newline at end of file diff --git a/example/darkmode/view/index.svelte b/example/darkmode/view/index.svelte new file mode 100644 index 00000000..9978fdab --- /dev/null +++ b/example/darkmode/view/index.svelte @@ -0,0 +1,36 @@ + + +
+

Change Theme

+
+ +
+
+ +