diff --git a/Cargo.lock b/Cargo.lock index b71dce5e..4c8b2ffd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -160,7 +160,7 @@ dependencies = [ "log", "ndk", "ndk-context", - "ndk-sys", + "ndk-sys 0.6.0+11769913", "num_enum", "thiserror 1.0.69", ] @@ -221,13 +221,27 @@ dependencies = [ "debug_timer", "kurbo 0.12.0", "peniko", - "pollster", + "pollster 0.4.0", "rustc-hash 2.1.1", "vello", - "wgpu", + "wgpu 26.0.1", "wgpu_context", ] +[[package]] +name = "anyrender_vello_cpu" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53ab47fd3c17dd144010b079f07e106b9d5d982c2916dcf73e8ad2f611d5becd" +dependencies = [ + "anyrender", + "debug_timer", + "kurbo 0.12.0", + "peniko", + "pixels_window_renderer", + "vello_cpu", +] + [[package]] name = "app_units" version = "0.7.8" @@ -273,6 +287,15 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b" +[[package]] +name = "ash" +version = "0.37.3+1.3.251" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e9c3835d686b0a6084ab4234fcd1b07dbf6e4767dce60874b12356a25ecd4a" +dependencies = [ + "libloading 0.7.4", +] + [[package]] name = "ash" version = "0.38.0+1.3.281" @@ -413,7 +436,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -453,7 +476,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -470,7 +493,7 @@ checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -669,7 +692,7 @@ checksum = "604fde5e028fea851ce1d8570bbdc034bec850d157f7569d10f347d06808c05c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -693,15 +716,30 @@ dependencies = [ "serde", ] +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec 0.6.3", +] + [[package]] name = "bit-set" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" dependencies = [ - "bit-vec", + "bit-vec 0.8.0", ] +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + [[package]] name = "bit-vec" version = "0.8.0" @@ -912,7 +950,7 @@ checksum = "f9abbd1bc6865053c427f7198e6af43bfdedc55ab791faed4fbd361d789575ff" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -989,9 +1027,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.44" +version = "1.2.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37521ac7aabe3d13122dc382493e20c9416f299d2ccd5b3a5340a2570cdeb0f3" +checksum = "35900b6c8d709fb1d854671ae27aeaa9eec2f8b01b364e1619a40da3e6fe2afe" dependencies = [ "find-msvc-tools", "jobserver", @@ -1032,6 +1070,12 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + [[package]] name = "cfg_aliases" version = "0.2.1" @@ -1126,6 +1170,16 @@ dependencies = [ "objc", ] +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width 0.1.14", +] + [[package]] name = "codespan-reporting" version = "0.12.0" @@ -1134,7 +1188,7 @@ checksum = "fe6d2e5af09e8c8ad56c969f2157a3d4238cebc7c55f0a517728c38f7b200f81" dependencies = [ "serde", "termcolor", - "unicode-width", + "unicode-width 0.2.2", ] [[package]] @@ -1142,6 +1196,9 @@ name = "color" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a18ef4657441fb193b65f34dc39b3781f0dfec23d3bd94d0eeb4e88cde421edb" +dependencies = [ + "bytemuck", +] [[package]] name = "color_quant" @@ -1149,6 +1206,37 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" +[[package]] +name = "com" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e17887fd17353b65b1b2ef1c526c83e26cd72e74f598a8dc1bee13a48f3d9f6" +dependencies = [ + "com_macros", +] + +[[package]] +name = "com_macros" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d375883580a668c7481ea6631fc1a8863e33cc335bf56bfad8d7e6d4b04b13a5" +dependencies = [ + "com_macros_support", + "proc-macro2", + "syn 1.0.109", +] + +[[package]] +name = "com_macros_support" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad899a1087a9296d5644792d7cb72b8e34c1bec8e7d4fbc002230169a6e8710c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "combine" version = "4.6.7" @@ -1170,9 +1258,9 @@ dependencies = [ [[package]] name = "const-serialize" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b4acbf274e71b0a53ff15f8669b86df421586a9fcac6398bc374c0b7146b6a3" +checksum = "fd339aa356cc6452308fad2ee56623f900a8e68bc0ab9360a0ddb8270e5640c8" dependencies = [ "const-serialize-macro", "serde", @@ -1180,13 +1268,13 @@ dependencies = [ [[package]] name = "const-serialize-macro" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2d3f3be18d39289c06c906cb7fb7ea1f027607ac5fa0cb0c4f1e91719042c52" +checksum = "797d158acb331e2a89d696343a27cd39bf7e36aaef33ba4799a5ef1526e24861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -1457,7 +1545,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" dependencies = [ "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -1466,6 +1554,17 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f27ae1dd37df86211c42e150270f82743308803d90a6f6e6651cd730d5e1732f" +[[package]] +name = "d3d12" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e3d747f100290a1ca24b752186f61f6637e1deffe3bf6320de6fcb29510a307" +dependencies = [ + "bitflags 2.10.0", + "libloading 0.8.9", + "winapi", +] + [[package]] name = "darling" version = "0.20.11" @@ -1496,7 +1595,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -1509,7 +1608,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -1520,7 +1619,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core 0.20.11", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -1531,7 +1630,7 @@ checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" dependencies = [ "darling_core 0.21.3", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -1585,7 +1684,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -1605,7 +1704,7 @@ checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", "unicode-xid", ] @@ -1621,9 +1720,9 @@ dependencies = [ [[package]] name = "dioxus" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9361dcb0cacb57f8af31010e1a3503404415ce5ff33dd83c760dfdcf505aded9" +checksum = "f76e820919058a685a1fdbb2ef4888c73ac77d623c39a7dfde2aa812947246be" dependencies = [ "dioxus-asset-resolver", "dioxus-cli-config", @@ -1656,9 +1755,9 @@ dependencies = [ [[package]] name = "dioxus-asset-resolver" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "954badc855b8e61d8880d204c7e3e2570daa59302c3843b2de1fae30ec266e64" +checksum = "7f6a124667ce5565c39fe2f33af45c21fe459c5bfcf7a8074ad12c9e9da5817c" dependencies = [ "dioxus-cli-config", "http", @@ -1667,7 +1766,7 @@ dependencies = [ "js-sys", "ndk", "ndk-context", - "ndk-sys", + "ndk-sys 0.6.0+11769913", "percent-encoding", "thiserror 2.0.17", "tokio", @@ -1677,18 +1776,18 @@ dependencies = [ [[package]] name = "dioxus-cli-config" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d28a6973d779e73f4b8ce705b1ea4c96f4083567ede862e734da2ab7c1dfc4b6" +checksum = "babc8eaf90379352bc4820830749fd231feb9312433d4094b4e7b79d912b3d96" dependencies = [ "wasm-bindgen", ] [[package]] name = "dioxus-config-macro" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9b5a9360dbf7a8499f67a96b8408f0c4d45222b0f19d7e42a7c49030b1a4085" +checksum = "30018b5b95567cee42febbb444d5e5e47dbe3e91fa6e44b9e571edad0184cd36" dependencies = [ "proc-macro2", "quote", @@ -1696,15 +1795,15 @@ dependencies = [ [[package]] name = "dioxus-config-macros" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "060c2e384709a434a74d24a676f4ccd61e7a97f812b0807fa71a8ef8896cfd3b" +checksum = "0a16b25f8761253ed5ffa4d0789376310fbbc1bbaa8190fc2f374db82c6285a1" [[package]] name = "dioxus-core" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "743e05cc98a6c7189e7df49791c0affb860cb858ba2a19dde4ecadf2a8729e8c" +checksum = "75468d08468919f783b0f7ee826802f4e8e66c5b5a0451245d861c211ca18216" dependencies = [ "anyhow", "const_format", @@ -1725,28 +1824,28 @@ dependencies = [ [[package]] name = "dioxus-core-macro" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa557c3d165eb2df73414f4678912e4595de80d6cd13566a3377f16c438c5ec3" +checksum = "f145abdb2a3f858456cb4382390863cf0398c228ad0733618f48891da7687be3" dependencies = [ "convert_case 0.8.0", "dioxus-rsx", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] name = "dioxus-core-types" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d16343cebee52e82686963ccd6f5590ebca567229bfa59aa3d598210f3a9fc0" +checksum = "36f5ecf5a51de06d78aded3b5f7516a258f53117cba718bc5706317a3c04c844" [[package]] name = "dioxus-desktop" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dfcfa2ae65f643a05583acb27e5a52b22de52b2f49583d012c8e58b6c495941" +checksum = "f493c74ff09410c5eadf42abd031d4b3d4032a4d5a2411c77d1d0d5156ca3687" dependencies = [ "async-trait", "base64", @@ -1770,12 +1869,12 @@ dependencies = [ "global-hotkey", "infer", "jni", - "lazy-js-bundle 0.7.0", + "lazy-js-bundle 0.7.1", "libc", "muda", "ndk", "ndk-context", - "ndk-sys", + "ndk-sys 0.6.0+11769913", "objc", "objc_id", "percent-encoding", @@ -1799,9 +1898,9 @@ dependencies = [ [[package]] name = "dioxus-devtools" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "419353dace2fb67ac7b35070a56c00a66c920c0191e7a81cf9c9ac8dd7ab3798" +checksum = "4eb2c5019b7fa72e8e6b21ba99e9263bd390c9a30bbf09793b72f4b57ed7c3d7" dependencies = [ "dioxus-cli-config", "dioxus-core", @@ -1820,9 +1919,9 @@ dependencies = [ [[package]] name = "dioxus-devtools-types" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6eb8755823ca644da88a50e80676330f4f0c1a40650af03d2fd617d3478a8e7" +checksum = "7b007cec5b8548281921c4e4678926a3936e9d6757e951380685cc6121a6f974" dependencies = [ "dioxus-core", "serde", @@ -1831,9 +1930,9 @@ dependencies = [ [[package]] name = "dioxus-document" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94cc73e120c260a07689353b09b8fdb0c49960fb88ba8e669992245c80720bb6" +checksum = "8c55bcae9aaf150d4a141c61b3826da5a7ac23dfff09726568525cd46336e9a2" dependencies = [ "dioxus-core", "dioxus-core-macro", @@ -1842,7 +1941,7 @@ dependencies = [ "futures-channel", "futures-util", "generational-box", - "lazy-js-bundle 0.7.0", + "lazy-js-bundle 0.7.1", "serde", "serde_json", "tracing", @@ -1850,9 +1949,9 @@ dependencies = [ [[package]] name = "dioxus-fullstack" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55dfce343a754869dfde344e41c79a3ec4737867f90501dcfe8850eceeb37ea" +checksum = "ff04cef82d6639eb15186f626298645dbd92978bf66dc3efd2e5984a2ff4a1ff" dependencies = [ "anyhow", "async-stream", @@ -1915,9 +2014,9 @@ dependencies = [ [[package]] name = "dioxus-fullstack-core" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f486f2b8864d1a0843189acbec74af6d9d206e82694ded6e5923a6c6f774b15" +checksum = "41281c7cd4d311a50933256e19a5d91d0d950ad350dd3232bd4321fdd3a59fb0" dependencies = [ "anyhow", "axum-core", @@ -1943,23 +2042,23 @@ dependencies = [ [[package]] name = "dioxus-fullstack-macro" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a59c844d648dae315b5aa264956f0c6fd9f34a5cedbf79fd0744820bf302bc5" +checksum = "ae73023c8b8fee2692fc50a28063336f0b6930e86727e30c1047c92d30805b49" dependencies = [ "const_format", "convert_case 0.8.0", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", "xxhash-rust", ] [[package]] name = "dioxus-history" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ea04ad918a08b81af66f1128f759162e33e8f7e7e062597e6dd542a45211905" +checksum = "dac73657da5c7a20629482d774b52f4a4f7cb57a520649f1d855d4073e809c98" dependencies = [ "dioxus-core", "tracing", @@ -1967,9 +2066,9 @@ dependencies = [ [[package]] name = "dioxus-hooks" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e7c1a9c7e8d2422198d082d03a9e1f4eb5789cdc1d73f1eb08e0d36a62fdfcb" +checksum = "7ffd445f16d64939e06cd71a1c63a665f383fda6b7882f4c6f8f1bd6efca2046" dependencies = [ "dioxus-core", "dioxus-signals", @@ -1984,9 +2083,9 @@ dependencies = [ [[package]] name = "dioxus-html" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe86f40430acb0ee310f91e7dbdd48ea4e26267dedab6e54f0c45f0c692db924" +checksum = "9f407fc73a9554a644872fcccc9faf762acad8f45158e3d67e42ab8dd42f4586" dependencies = [ "async-trait", "bytes", @@ -2001,7 +2100,7 @@ dependencies = [ "futures-util", "generational-box", "keyboard-types", - "lazy-js-bundle 0.7.0", + "lazy-js-bundle 0.7.1", "rustversion", "serde", "serde_json", @@ -2011,14 +2110,14 @@ dependencies = [ [[package]] name = "dioxus-html-internal-macro" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "267ca3487501aa1b95a5d65554ee36839da660b03174146c5c27d54014067abd" +checksum = "a968aae4bc92de87cbac3d0d043803b25a7c62c187841e61adcc9b49917c2b2a" dependencies = [ "convert_case 0.8.0", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -2035,15 +2134,15 @@ dependencies = [ [[package]] name = "dioxus-interpreter-js" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14c429cd5057cec2eb00acef02a699ebd359a98d392629464b2e1c350eaed8ce" +checksum = "83ab170d89308399205f8ad3d43d8d419affe317016b41ca0695186f7593cba2" dependencies = [ "dioxus-core", "dioxus-core-types", "dioxus-html", "js-sys", - "lazy-js-bundle 0.7.0", + "lazy-js-bundle 0.7.1", "rustc-hash 2.1.1", "serde", "sledgehammer_bindgen", @@ -2055,9 +2154,9 @@ dependencies = [ [[package]] name = "dioxus-liveview" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36d558d71ee41b33d2b35fd39444bfaab65fbda0b608c3eba33ea8ff97247115" +checksum = "ca4f2850ec1a468c6f15b578c43218562d2309aadaf2b8bf17f54ce30e72f594" dependencies = [ "axum", "dioxus-cli-config", @@ -2083,9 +2182,9 @@ dependencies = [ [[package]] name = "dioxus-logger" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a54751cf6aa00132c8a17343ad8d8cdb587d67a4b71acfc19ed78a924128edb" +checksum = "42237934c6a67f5ed9a8c37e47ca980ee7cfec9e783a9a1f8c2e36c8b96ae74b" dependencies = [ "dioxus-cli-config", "tracing", @@ -2095,12 +2194,13 @@ dependencies = [ [[package]] name = "dioxus-native" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ba97035d9569abc5b71e341714c1f3c3ea88dd0376be8f50c024f19432c15e3" +checksum = "1468a33d63d9e23b749a0630b48bcd21e65b60c9c2c0a52d1aeaee52c034747c" dependencies = [ "anyrender", "anyrender_vello", + "anyrender_vello_cpu", "blitz-dom", "blitz-html", "blitz-net", @@ -2125,9 +2225,9 @@ dependencies = [ [[package]] name = "dioxus-native-dom" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62386d7c609196d856e87d638e2652916790a9eb1af089205e23d256b0fdcf2d" +checksum = "1dc2c524c5bc84a998db9ca22075a8b375ff4cfe1415abe2cc84ee7f653e086b" dependencies = [ "blitz-dom", "blitz-traits", @@ -2153,7 +2253,7 @@ dependencies = [ [[package]] name = "dioxus-primitives" version = "0.0.1" -source = "git+https://github.com/DioxusLabs/components#39b30b559fcdce71cee5d8cbf67f925b0366e1c3" +source = "git+https://github.com/DioxusLabs/components#8e25631c7d4234ee070509156ed2abebb7b1d6e9" dependencies = [ "dioxus", "dioxus-time", @@ -2165,9 +2265,9 @@ dependencies = [ [[package]] name = "dioxus-router" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "577cc2680066242ef0e672c379c7b63072dee838a7dac6a4296f0c768ab2f72f" +checksum = "fdf1b95b7cafd07a2b39651ab2b146e4aa72acb0295cd52f422b7db5e2ab6eeb" dependencies = [ "dioxus-cli-config", "dioxus-core", @@ -2186,9 +2286,9 @@ dependencies = [ [[package]] name = "dioxus-router-macro" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a924da6e4b92053266b1f153292bd2282ce1ff2b035b29002f1520112a4d00e5" +checksum = "a292046c5d166046ae027fce47b177a733946cf1efc8d006de9f4064f69110cd" dependencies = [ "base16", "digest", @@ -2196,26 +2296,26 @@ dependencies = [ "quote", "sha2", "slab", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] name = "dioxus-rsx" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e290f814c6ee06f34d40bb5f3db976500f39e1776c80984fb23815377c2c9cd0" +checksum = "f026380dfda8b93ad995c0a90a62a17b8afeb246baff1b781a52c7b1b3ebd791" dependencies = [ "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] name = "dioxus-server" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b3b6b8658b79b05c44e66dd934ca3e419a175d1ea9c130b07aa6512605e8df5" +checksum = "012e972802d2dc4f4afab89bb4c7695e6a7b8b8a81b6bc30d43c1a42e11eb6ff" dependencies = [ "anyhow", "async-trait", @@ -2271,9 +2371,9 @@ dependencies = [ [[package]] name = "dioxus-signals" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fce8fe43f49769d7a05bef9e1acafcefc9b5f7da2b9bb58e0bde12a145028b9" +checksum = "3895cc17ff5b43ada07743111be586e7a927ed7ec511457020e4235e13e63fe6" dependencies = [ "dioxus-core", "futures-channel", @@ -2287,9 +2387,9 @@ dependencies = [ [[package]] name = "dioxus-ssr" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c180307efbf0f2cb64ad125fd4e6e00d0586dba73875bdea0d6587f5c89524b7" +checksum = "592391fc30a77f94bc5a3385d1569052907e3b3cecb28099671b9d5801dee6c6" dependencies = [ "askama_escape", "dioxus-core", @@ -2299,9 +2399,9 @@ dependencies = [ [[package]] name = "dioxus-stores" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01f9b29b4486f4aa515ab59b5d5b9177b1abf1a3f4c1940cedc8031ca6c11933" +checksum = "8521729ac35f362476ac4eb7d1c4ab79e7e92a0facfdea3ee978c0ddf7108d37" dependencies = [ "dioxus-core", "dioxus-signals", @@ -2310,20 +2410,20 @@ dependencies = [ [[package]] name = "dioxus-stores-macro" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d63865f35106c145a11b1072eb84dd9d0d4ca4a78861ad666c297ebae8f42d" +checksum = "23a733d2684dc843e81954f6176b3353e4cfc71b6978a8e464591bb5536f610b" dependencies = [ "convert_case 0.8.0", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] name = "dioxus-time" version = "0.7.0" -source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#7c169af933a2a09570b6cffbbb73151c2ff1cffc" +source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#8c868ac1d60e3232e3f16f6195d6deb3c016de17" dependencies = [ "dioxus", "futures", @@ -2333,9 +2433,9 @@ dependencies = [ [[package]] name = "dioxus-web" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d877058b49e547fee2b0fe26af17018142983262a9dd3f739963903799aea8e" +checksum = "76155ecd44535e7c096ec8c5aac4a945899e47567ead4869babdaa74f3f9bca0" dependencies = [ "dioxus-cli-config", "dioxus-core", @@ -2352,7 +2452,7 @@ dependencies = [ "generational-box", "gloo-timers", "js-sys", - "lazy-js-bundle 0.7.0", + "lazy-js-bundle 0.7.1", "rustc-hash 2.1.1", "send_wrapper", "serde", @@ -2412,7 +2512,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -2444,7 +2544,7 @@ checksum = "788160fb30de9cdd857af31c6a2675904b16ece8fc2737b2c7127ba368c9d0f4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -2528,7 +2628,7 @@ checksum = "67c78a4d8fdf9953a5c9d458f9efe940fd97a0cab0941c075a813ac594733827" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -2549,7 +2649,7 @@ dependencies = [ "darling 0.21.3", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -2620,6 +2720,15 @@ dependencies = [ "simd-adler32", ] +[[package]] +name = "fearless_simd" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fb2907d1f08b2b316b9223ced5b0e89d87028ba8deae9764741dba8ff7f3903" +dependencies = [ + "bytemuck", +] + [[package]] name = "field-offset" version = "0.3.6" @@ -2726,9 +2835,9 @@ dependencies = [ [[package]] name = "font-types" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "511e2c18a516c666d27867d2f9821f76e7d591f762e9fc41dd6cc5c90fe54b0b" +checksum = "39a654f404bbcbd48ea58c617c2993ee91d1cb63727a37bf2323a4edeed1b8c5" dependencies = [ "bytemuck", ] @@ -2806,7 +2915,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -2920,7 +3029,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -3049,9 +3158,9 @@ dependencies = [ [[package]] name = "generational-box" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f067a79c49f237b1017258357a9789477be4f47f11422c74547a8bec189adb4" +checksum = "b3c1ae09dfd2d455484a54b56129b9821241c4b0e412227806b6c3730cd18a29" dependencies = [ "parking_lot", "tracing", @@ -3083,7 +3192,7 @@ version = "0.2.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfe4fbac503b8d1f88e6676011885f34b7174f46e59956bba534ba83abded4df" dependencies = [ - "unicode-width", + "unicode-width 0.2.2", ] [[package]] @@ -3211,7 +3320,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -3287,6 +3396,18 @@ dependencies = [ "web-sys", ] +[[package]] +name = "glow" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd348e04c43b32574f2de31c8bb397d96c9fcfa1371bd4ca6d8bdc464ab121b1" +dependencies = [ + "js-sys", + "slotmap", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "glow" version = "0.16.0" @@ -3299,6 +3420,15 @@ dependencies = [ "web-sys", ] +[[package]] +name = "glutin_wgl_sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8098adac955faa2d31079b65dc48841251f69efd3ac25477903fc424362ead" +dependencies = [ + "gl_generator", +] + [[package]] name = "glutin_wgl_sys" version = "0.6.1" @@ -3338,6 +3468,19 @@ dependencies = [ "bitflags 2.10.0", ] +[[package]] +name = "gpu-allocator" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f56f6318968d03c18e1bcf4857ff88c61157e9da8e47c5f29055d60e1228884" +dependencies = [ + "log", + "presser", + "thiserror 1.0.69", + "winapi", + "windows 0.52.0", +] + [[package]] name = "gpu-allocator" version = "0.27.0" @@ -3350,6 +3493,17 @@ dependencies = [ "windows 0.58.0", ] +[[package]] +name = "gpu-descriptor" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc11df1ace8e7e564511f53af41f3e42ddc95b56fd07b3f4445d2a6048bc682c" +dependencies = [ + "bitflags 2.10.0", + "gpu-descriptor-types 0.1.2", + "hashbrown 0.14.5", +] + [[package]] name = "gpu-descriptor" version = "0.3.2" @@ -3357,10 +3511,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b89c83349105e3732062a895becfc71a8f921bb71ecbbdd8ff99263e3b53a0ca" dependencies = [ "bitflags 2.10.0", - "gpu-descriptor-types", + "gpu-descriptor-types 0.2.0", "hashbrown 0.15.5", ] +[[package]] +name = "gpu-descriptor-types" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bf0b36e6f090b7e1d8a4b49c0cb81c1f8376f72198c65dd3ad9ff3556b8b78c" +dependencies = [ + "bitflags 2.10.0", +] + [[package]] name = "gpu-descriptor-types" version = "0.2.0" @@ -3425,7 +3588,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -3487,6 +3650,10 @@ name = "hashbrown" version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", + "allocator-api2", +] [[package]] name = "hashbrown" @@ -3510,6 +3677,21 @@ dependencies = [ "foldhash 0.2.0", ] +[[package]] +name = "hassle-rs" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af2a7e73e1f34c48da31fb668a907f250794837e08faa144fd24f0b8b741e890" +dependencies = [ + "bitflags 2.10.0", + "com", + "libc", + "libloading 0.8.9", + "thiserror 1.0.69", + "widestring", + "winapi", +] + [[package]] name = "headers" version = "0.4.1" @@ -3882,7 +4064,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -4031,9 +4213,9 @@ checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" [[package]] name = "iri-string" -version = "0.7.8" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" +checksum = "4f867b9d1d896b67beb18518eda36fdb77a32ea590de864f1325b294a6d14397" dependencies = [ "memchr", "serde", @@ -4189,9 +4371,9 @@ checksum = "e49596223b9d9d4947a14a25c142a6e7d8ab3f27eb3ade269d238bb8b5c267e2" [[package]] name = "lazy-js-bundle" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb1a786b3e81c7a8c1809f8e430cc53f26b37695d929ba41bc30d71679c80e0a" +checksum = "409273b42d0e3ae7c8ce6b8cfbc6a27b7c7d83bbb94fc7f93f22cc9b90eea078" [[package]] name = "lazy_static" @@ -4377,7 +4559,7 @@ checksum = "1b27834086c65ec3f9387b096d66e99f221cf081c2b738042aa252bcd41204e3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -4396,15 +4578,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f44db74bde26fdf427af23f1d146c211aed857c59e3be750cf2617f6b0b05c94" dependencies = [ "proc-macro2", - "syn 2.0.108", + "syn 2.0.110", "synstructure", ] [[package]] name = "manganis" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcdad2e00822f2705d142c76843e4d0de796754e1dfa7e459e4e2b1742d6e632" +checksum = "124f8f094eb75783b38209ce4d534b9617da4efac652802d9bafe05043a3ec95" dependencies = [ "const-serialize", "manganis-core", @@ -4413,9 +4595,9 @@ dependencies = [ [[package]] name = "manganis-core" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "058d5b28351649020f1a1a3c36a8019a5e1d747f4103e3adb6b5eef15f1683e0" +checksum = "41fbd1fb8c5aabcc54c6b02dbc968e1c89c28f3e543f2789ef9e3ce45dbdf5df" dependencies = [ "const-serialize", "dioxus-cli-config", @@ -4425,16 +4607,16 @@ dependencies = [ [[package]] name = "manganis-macro" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd5449ca340d41990d79be6accc063aa9b6a70b83766a0210d5230dd76e40dd7" +checksum = "45d6fec2a8249739bb30b53a08ecbb217f76096c08f1053f38ec3981ba424c11" dependencies = [ "dunce", "macro-string", "manganis-core", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -4470,7 +4652,7 @@ checksum = "88a9689d8d44bf9964484516275f5cd4c9b59457a6940c1d5d0ecbb94510a36b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -4481,7 +4663,7 @@ checksum = "ac84fd3f360fcc43dc5f5d186f02a94192761a080e8bc58621ad4d12296a58cf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -4538,6 +4720,21 @@ dependencies = [ "autocfg", ] +[[package]] +name = "metal" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c43f73953f8cbe511f021b58f18c3ce1c3d1ae13fe953293e13345bf83217f25" +dependencies = [ + "bitflags 2.10.0", + "block", + "core-graphics-types 0.1.3", + "foreign-types 0.5.0", + "log", + "objc", + "paste", +] + [[package]] name = "metal" version = "0.32.0" @@ -4628,6 +4825,26 @@ dependencies = [ "version_check", ] +[[package]] +name = "naga" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50e3524642f53d9af419ab5e8dd29d3ba155708267667c2f3f06c88c9e130843" +dependencies = [ + "bit-set 0.5.3", + "bitflags 2.10.0", + "codespan-reporting 0.11.1", + "hexf-parse", + "indexmap", + "log", + "num-traits", + "rustc-hash 1.1.0", + "spirv", + "termcolor", + "thiserror 1.0.69", + "unicode-xid", +] + [[package]] name = "naga" version = "26.0.0" @@ -4635,11 +4852,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "916cbc7cb27db60be930a4e2da243cf4bc39569195f22fd8ee419cd31d5b662c" dependencies = [ "arrayvec", - "bit-set", + "bit-set 0.8.0", "bitflags 2.10.0", "cfg-if", - "cfg_aliases", - "codespan-reporting", + "cfg_aliases 0.2.1", + "codespan-reporting 0.12.0", "half", "hashbrown 0.15.5", "hexf-parse", @@ -4680,7 +4897,7 @@ dependencies = [ "bitflags 2.10.0", "jni-sys", "log", - "ndk-sys", + "ndk-sys 0.6.0+11769913", "num_enum", "raw-window-handle 0.6.2", "thiserror 1.0.69", @@ -4692,6 +4909,15 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" +[[package]] +name = "ndk-sys" +version = "0.5.0+25.2.9519653" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c196769dd60fd4f363e11d948139556a344e79d451aeb2fa2fd040738ef7691" +dependencies = [ + "jni-sys", +] + [[package]] name = "ndk-sys" version = "0.6.0+11769913" @@ -4715,7 +4941,7 @@ checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ "bitflags 2.10.0", "cfg-if", - "cfg_aliases", + "cfg_aliases 0.2.1", "libc", "memoffset", ] @@ -4728,7 +4954,7 @@ checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" dependencies = [ "bitflags 2.10.0", "cfg-if", - "cfg_aliases", + "cfg_aliases 0.2.1", "libc", "memoffset", ] @@ -4753,7 +4979,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -4804,7 +5030,7 @@ dependencies = [ "proc-macro-crate 3.4.0", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -4814,6 +5040,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" dependencies = [ "malloc_buf", + "objc_exception", ] [[package]] @@ -5135,6 +5362,15 @@ dependencies = [ "objc2-foundation 0.3.2", ] +[[package]] +name = "objc_exception" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4" +dependencies = [ + "cc", +] + [[package]] name = "objc_id" version = "0.1.1" @@ -5174,9 +5410,9 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.74" +version = "0.10.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24ad14dd45412269e1a30f52ad8f0664f0f4f4a89ee8fe28c3b3527021ebb654" +checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328" dependencies = [ "bitflags 2.10.0", "cfg-if", @@ -5195,7 +5431,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -5206,9 +5442,9 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-sys" -version = "0.9.110" +version = "0.9.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a9f0075ba3c21b09f8e8b2026584b1d18d49388648f2fbbf3c97ea8deced8e2" +checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321" dependencies = [ "cc", "libc", @@ -5224,9 +5460,9 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "orbclient" -version = "0.3.48" +version = "0.3.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba0b26cec2e24f08ed8bb31519a9333140a6599b867dac464bb150bdb796fd43" +checksum = "247ad146e19b9437f8604c21f8652423595cf710ad108af40e77d3ae6e96b827" dependencies = [ "libredox", ] @@ -5339,6 +5575,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3c76095c9a636173600478e0373218c7b955335048c2bcd12dc6a79657649d8" dependencies = [ + "bytemuck", "color", "kurbo 0.12.0", "linebender_resource_handle", @@ -5455,7 +5692,7 @@ dependencies = [ "phf_shared 0.11.3", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -5508,7 +5745,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -5534,6 +5771,31 @@ dependencies = [ "futures-io", ] +[[package]] +name = "pixels" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "518d43cd70c5381d4c7bd4bf47ee344beee99b58b0587adcb198cc713ff0dfb5" +dependencies = [ + "bytemuck", + "pollster 0.3.0", + "raw-window-handle 0.6.2", + "thiserror 1.0.69", + "ultraviolet", + "wgpu 0.19.4", +] + +[[package]] +name = "pixels_window_renderer" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5973b55d585de980b6a1db68b116c8c741c18ab5a5699621aee7cac343aea58" +dependencies = [ + "anyrender", + "debug_timer", + "pixels", +] + [[package]] name = "pkg-config" version = "0.3.32" @@ -5580,6 +5842,12 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "pollster" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22686f4785f02a4fcc856d3b3bb19bf6c8160d103f7a99cc258bddd0251dc7f2" + [[package]] name = "pollster" version = "0.4.0" @@ -5719,7 +5987,7 @@ checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", "version_check", ] @@ -5805,7 +6073,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" dependencies = [ "bytes", - "cfg_aliases", + "cfg_aliases 0.2.1", "pin-project-lite", "quinn-proto", "quinn-udp", @@ -5845,7 +6113,7 @@ version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" dependencies = [ - "cfg_aliases", + "cfg_aliases 0.2.1", "libc", "once_cell", "socket2", @@ -5855,9 +6123,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.41" +version = "1.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" +checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" dependencies = [ "proc-macro2", ] @@ -6034,7 +6302,7 @@ checksum = "6717cf23b488adf64b9d711329542ba34de147df262370221940dfabc2c91358" dependencies = [ "bytemuck", "core_maths", - "font-types 0.10.0", + "font-types 0.10.1", ] [[package]] @@ -6154,7 +6422,7 @@ dependencies = [ "objc2-app-kit 0.3.2", "objc2-core-foundation", "objc2-foundation 0.3.2", - "pollster", + "pollster 0.4.0", "raw-window-handle 0.6.2", "urlencoding", "wasm-bindgen", @@ -6232,9 +6500,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.34" +version = "0.23.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a9586e9ee2b4f8fab52a0048ca7334d7024eef48e2cb9407e3497bb7cab7fa7" +checksum = "533f54bc6a7d4f647e46ad909549eda97bf5afc1585190ef692b4286b198bd8f" dependencies = [ "once_cell", "ring", @@ -6295,6 +6563,15 @@ version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +[[package]] +name = "safe_arch" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b02de82ddbe1b636e6170c21be622223aea188ef2e139be0a5b219ec215323" +dependencies = [ + "bytemuck", +] + [[package]] name = "same-file" version = "1.0.6" @@ -6459,7 +6736,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -6505,7 +6782,7 @@ checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -6675,7 +6952,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f62f06db0370222f7f498ef478fce9f8df5828848d1d3517e3331936d7074f55" dependencies = [ "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -6858,7 +7135,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -6944,7 +7221,7 @@ dependencies = [ "darling 0.20.11", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", "synstructure", ] @@ -7017,9 +7294,9 @@ dependencies = [ [[package]] name = "subsecond" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e778134c310fa884270b226bbf58df76da727acf921f46834b0af896d739235c" +checksum = "834e8caec50249083ee6972a2f7645c4baadcb39d49ea801da1dc1d5e1c2ccb9" dependencies = [ "js-sys", "libc", @@ -7036,9 +7313,9 @@ dependencies = [ [[package]] name = "subsecond-types" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcfc02dd02f2ce7c9aa6c0eb4f490fc455925c2590de7a3c54dde088c3ef481d" +checksum = "c6beffea67e72a7a530990b270fd0277971eae564fdc10c1e0080e928b477fab" dependencies = [ "serde", ] @@ -7089,9 +7366,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.108" +version = "2.0.110" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da58917d35242480a05c2897064da0a80589a2a0476c9a3f2fdc83b53502e917" +checksum = "a99801b5bd34ede4cf3fc688c5919368fea4e4814a4664359503e6015b280aea" dependencies = [ "proc-macro2", "quote", @@ -7115,7 +7392,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -7208,7 +7485,7 @@ dependencies = [ "log", "ndk", "ndk-context", - "ndk-sys", + "ndk-sys 0.6.0+11769913", "objc2 0.6.3", "objc2-app-kit 0.3.2", "objc2-foundation 0.3.2", @@ -7234,7 +7511,7 @@ checksum = "f4e16beb8b2ac17db28eab8bca40e62dbfbb34c0fcdc6d9826b11b7b5d047dfd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -7316,7 +7593,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -7327,7 +7604,7 @@ checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -7453,7 +7730,7 @@ dependencies = [ "darling 0.20.11", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", "synstructure", ] @@ -7482,7 +7759,7 @@ checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -7543,9 +7820,9 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.16" +version = "0.7.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" +checksum = "2efa149fe76073d6e8fd97ef4f4eca7b67f599660115591483572e406e165594" dependencies = [ "bytes", "futures-core", @@ -7707,7 +7984,7 @@ checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -7853,6 +8130,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "ultraviolet" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a28554d13eb5daba527cc1b91b6c341372a0ae45ed277ffb2c6fbc04f319d7e" +dependencies = [ + "wide", +] + [[package]] name = "uluru" version = "3.1.0" @@ -7901,7 +8187,7 @@ checksum = "a1249a628de3ad34b821ecb1001355bca3940bcb2f88558f1a8bd82e977f75b5" dependencies = [ "proc-macro-hack", "quote", - "syn 2.0.108", + "syn 2.0.110", "unic-langid-impl", ] @@ -7959,6 +8245,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1d386ff53b415b7fe27b50bb44679e2cc4660272694b7b6f3326d8480823a94" +[[package]] +name = "unicode-width" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" + [[package]] name = "unicode-width" version = "0.2.2" @@ -8079,7 +8371,32 @@ dependencies = [ "thiserror 2.0.17", "vello_encoding", "vello_shaders", - "wgpu", + "wgpu 26.0.1", +] + +[[package]] +name = "vello_common" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a235ba928b3109ad9e7696270edb09445a52ae1c7c08e6d31a19b1cdd6cbc24a" +dependencies = [ + "bytemuck", + "fearless_simd", + "hashbrown 0.15.5", + "log", + "peniko", + "skrifa 0.37.0", + "smallvec", +] + +[[package]] +name = "vello_cpu" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0bd1fcf9c1814f17a491e07113623d44e3ec1125a9f3401f5e047d6d326da21" +dependencies = [ + "bytemuck", + "vello_common", ] [[package]] @@ -8103,16 +8420,16 @@ checksum = "8c381dde4e7d0d7957df0c0e3f8a7cc0976762d3972d97da5c71464e57ffefd3" dependencies = [ "bytemuck", "log", - "naga", + "naga 26.0.0", "thiserror 2.0.17", "vello_encoding", ] [[package]] name = "version-compare" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" +checksum = "03c2856837ef78f57382f06b2b8563a2f512f7185d732608fd9176cb3b8edf0e" [[package]] name = "version_check" @@ -8164,7 +8481,7 @@ checksum = "59195a1db0e95b920366d949ba5e0d3fc0e70b67c09be15ce5abb790106b0571" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -8233,7 +8550,7 @@ dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", "wasm-bindgen-shared", ] @@ -8462,9 +8779,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b130c0d2d49f8b6889abc456e795e82525204f27c42cf767cf0d7734e089b8" +checksum = "b2878ef029c47c6e8cf779119f20fcf52bde7ad42a731b2a304bc221df17571e" dependencies = [ "rustls-pki-types", ] @@ -8491,7 +8808,7 @@ checksum = "1d228f15bba3b9d56dde8bddbee66fa24545bd17b48d5128ccf4a8742b18e431" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -8507,9 +8824,34 @@ dependencies = [ [[package]] name = "weezl" -version = "0.1.10" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a751b3277700db47d3e574514de2eced5e54dc8a5436a3bf7a0b248b2cee16f3" +checksum = "009936b22a61d342859b5f0ea64681cbb35a358ab548e2a44a8cf0dac2d980b8" + +[[package]] +name = "wgpu" +version = "0.19.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbd7311dbd2abcfebaabf1841a2824ed7c8be443a0f29166e5d3c6a53a762c01" +dependencies = [ + "arrayvec", + "cfg-if", + "cfg_aliases 0.1.1", + "js-sys", + "log", + "naga 0.19.2", + "parking_lot", + "profiling", + "raw-window-handle 0.6.2", + "smallvec", + "static_assertions", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "wgpu-core 0.19.4", + "wgpu-hal 0.19.5", + "wgpu-types 0.19.2", +] [[package]] name = "wgpu" @@ -8520,12 +8862,12 @@ dependencies = [ "arrayvec", "bitflags 2.10.0", "cfg-if", - "cfg_aliases", + "cfg_aliases 0.2.1", "document-features", "hashbrown 0.15.5", "js-sys", "log", - "naga", + "naga 26.0.0", "parking_lot", "portable-atomic", "profiling", @@ -8535,9 +8877,35 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "wgpu-core", - "wgpu-hal", - "wgpu-types", + "wgpu-core 26.0.1", + "wgpu-hal 26.0.6", + "wgpu-types 26.0.0", +] + +[[package]] +name = "wgpu-core" +version = "0.19.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28b94525fc99ba9e5c9a9e24764f2bc29bad0911a7446c12f446a8277369bf3a" +dependencies = [ + "arrayvec", + "bit-vec 0.6.3", + "bitflags 2.10.0", + "cfg_aliases 0.1.1", + "codespan-reporting 0.11.1", + "indexmap", + "log", + "naga 0.19.2", + "once_cell", + "parking_lot", + "profiling", + "raw-window-handle 0.6.2", + "rustc-hash 1.1.0", + "smallvec", + "thiserror 1.0.69", + "web-sys", + "wgpu-hal 0.19.5", + "wgpu-types 0.19.2", ] [[package]] @@ -8547,15 +8915,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5f62f1053bd28c2268f42916f31588f81f64796e2ff91b81293515017ca8bd9" dependencies = [ "arrayvec", - "bit-set", - "bit-vec", + "bit-set 0.8.0", + "bit-vec 0.8.0", "bitflags 2.10.0", - "cfg_aliases", + "cfg_aliases 0.2.1", "document-features", "hashbrown 0.15.5", "indexmap", "log", - "naga", + "naga 26.0.0", "once_cell", "parking_lot", "portable-atomic", @@ -8567,8 +8935,8 @@ dependencies = [ "wgpu-core-deps-apple", "wgpu-core-deps-emscripten", "wgpu-core-deps-windows-linux-android", - "wgpu-hal", - "wgpu-types", + "wgpu-hal 26.0.6", + "wgpu-types 26.0.0", ] [[package]] @@ -8577,7 +8945,7 @@ version = "26.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "18ae5fbde6a4cbebae38358aa73fcd6e0f15c6144b67ef5dc91ded0db125dbdf" dependencies = [ - "wgpu-hal", + "wgpu-hal 26.0.6", ] [[package]] @@ -8586,7 +8954,7 @@ version = "26.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7670e390f416006f746b4600fdd9136455e3627f5bd763abf9a65daa216dd2d" dependencies = [ - "wgpu-hal", + "wgpu-hal 26.0.6", ] [[package]] @@ -8595,7 +8963,52 @@ version = "26.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "720a5cb9d12b3d337c15ff0e24d3e97ed11490ff3f7506e7f3d98c68fa5d6f14" dependencies = [ - "wgpu-hal", + "wgpu-hal 26.0.6", +] + +[[package]] +name = "wgpu-hal" +version = "0.19.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfabcfc55fd86611a855816326b2d54c3b2fd7972c27ce414291562650552703" +dependencies = [ + "android_system_properties", + "arrayvec", + "ash 0.37.3+1.3.251", + "bit-set 0.5.3", + "bitflags 2.10.0", + "block", + "cfg_aliases 0.1.1", + "core-graphics-types 0.1.3", + "d3d12", + "glow 0.13.1", + "glutin_wgl_sys 0.5.0", + "gpu-alloc", + "gpu-allocator 0.25.0", + "gpu-descriptor 0.2.4", + "hassle-rs", + "js-sys", + "khronos-egl", + "libc", + "libloading 0.8.9", + "log", + "metal 0.27.0", + "naga 0.19.2", + "ndk-sys 0.5.0+25.2.9519653", + "objc", + "once_cell", + "parking_lot", + "profiling", + "range-alloc", + "raw-window-handle 0.6.2", + "renderdoc-sys", + "rustc-hash 1.1.0", + "smallvec", + "thiserror 1.0.69", + "wasm-bindgen", + "web-sys", + "wgpu-types 0.19.2", + "winapi", ] [[package]] @@ -8606,28 +9019,28 @@ checksum = "a8d0e67224cc7305b3b4eb2cc57ca4c4c3afc665c1d1bee162ea806e19c47bdd" dependencies = [ "android_system_properties", "arrayvec", - "ash", - "bit-set", + "ash 0.38.0+1.3.281", + "bit-set 0.8.0", "bitflags 2.10.0", "block", "bytemuck", "cfg-if", - "cfg_aliases", + "cfg_aliases 0.2.1", "core-graphics-types 0.2.0", - "glow", - "glutin_wgl_sys", + "glow 0.16.0", + "glutin_wgl_sys 0.6.1", "gpu-alloc", - "gpu-allocator", - "gpu-descriptor", + "gpu-allocator 0.27.0", + "gpu-descriptor 0.3.2", "hashbrown 0.15.5", "js-sys", "khronos-egl", "libc", "libloading 0.8.9", "log", - "metal", - "naga", - "ndk-sys", + "metal 0.32.0", + "naga 26.0.0", + "ndk-sys 0.6.0+11769913", "objc", "ordered-float", "parking_lot", @@ -8641,11 +9054,22 @@ dependencies = [ "thiserror 2.0.17", "wasm-bindgen", "web-sys", - "wgpu-types", + "wgpu-types 26.0.0", "windows 0.58.0", "windows-core 0.58.0", ] +[[package]] +name = "wgpu-types" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b671ff9fb03f78b46ff176494ee1ebe7d603393f42664be55b64dc8d53969805" +dependencies = [ + "bitflags 2.10.0", + "js-sys", + "web-sys", +] + [[package]] name = "wgpu-types" version = "26.0.0" @@ -8667,9 +9091,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "066bd52170313ca33ba22c7cdc442bf9dbc06a1539eed1719ff7ae63386c0cae" dependencies = [ "futures-intrusive", - "wgpu", + "wgpu 26.0.1", +] + +[[package]] +name = "wide" +version = "0.7.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce5da8ecb62bcd8ec8b7ea19f69a51275e91299be594ea5cc6ef7819e16cd03" +dependencies = [ + "bytemuck", + "safe_arch", ] +[[package]] +name = "widestring" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72069c3113ab32ab29e5584db3c6ec55d416895e60715417b5b883a357c3e471" + [[package]] name = "winapi" version = "0.3.9" @@ -8701,6 +9141,16 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +dependencies = [ + "windows-core 0.52.0", + "windows-targets 0.52.6", +] + [[package]] name = "windows" version = "0.58.0" @@ -8733,6 +9183,15 @@ dependencies = [ "windows-core 0.61.2", ] +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-core" version = "0.58.0" @@ -8778,7 +9237,7 @@ checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -8789,7 +9248,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -8800,7 +9259,7 @@ checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -8811,7 +9270,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -9146,7 +9605,7 @@ dependencies = [ "block2 0.5.1", "bytemuck", "calloop", - "cfg_aliases", + "cfg_aliases 0.2.1", "concurrent-queue", "core-foundation 0.9.4", "core-graphics 0.23.2", @@ -9421,7 +9880,7 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", "synstructure", ] @@ -9510,7 +9969,7 @@ checksum = "709ab20fc57cb22af85be7b360239563209258430bccf38d8b979c5a2ae3ecce" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", "zbus-lockstep", "zbus_xml", "zvariant 4.2.0", @@ -9525,7 +9984,7 @@ dependencies = [ "proc-macro-crate 3.4.0", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", "zvariant_utils 2.1.0", ] @@ -9538,7 +9997,7 @@ dependencies = [ "proc-macro-crate 3.4.0", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", "zbus_names 4.2.0", "zvariant 5.8.0", "zvariant_utils 3.2.1", @@ -9603,7 +10062,7 @@ checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -9623,7 +10082,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", "synstructure", ] @@ -9652,7 +10111,7 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -9707,7 +10166,7 @@ dependencies = [ "proc-macro-crate 3.4.0", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", "zvariant_utils 2.1.0", ] @@ -9720,7 +10179,7 @@ dependencies = [ "proc-macro-crate 3.4.0", "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", "zvariant_utils 3.2.1", ] @@ -9732,7 +10191,7 @@ checksum = "c51bcff7cc3dbb5055396bcf774748c3dab426b4b8659046963523cee4808340" dependencies = [ "proc-macro2", "quote", - "syn 2.0.108", + "syn 2.0.110", ] [[package]] @@ -9744,6 +10203,6 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 2.0.108", + "syn 2.0.110", "winnow 0.7.13", ] diff --git a/README.md b/README.md index 602a8922..aaa67e6f 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ We're still in the early days - Many components are still being created and stab - [x] Checkbox - [x] Collapsible - [x] Context Menu -- [ ] Date Picker +- [x] Date Picker - [x] Dialog - [x] Dropdown Menu - [x] Hover Card diff --git a/preview/src/components/calendar/component.rs b/preview/src/components/calendar/component.rs index 35c8fce4..a989f70a 100644 --- a/preview/src/components/calendar/component.rs +++ b/preview/src/components/calendar/component.rs @@ -1,7 +1,8 @@ use dioxus::prelude::*; use dioxus_primitives::calendar::{ - self, CalendarGridProps, CalendarHeaderProps, CalendarMonthTitleProps, CalendarNavigationProps, - CalendarProps, CalendarSelectMonthProps, CalendarSelectYearProps, + self, CalendarDayProps, CalendarGridProps, CalendarHeaderProps, CalendarMonthTitleProps, + CalendarNavigationProps, CalendarProps, CalendarSelectMonthProps, CalendarSelectYearProps, + RangeCalendarProps, }; #[component] @@ -21,6 +22,32 @@ pub fn Calendar(props: CalendarProps) -> Element { first_day_of_week: props.first_day_of_week, min_date: props.min_date, max_date: props.max_date, + disabled_ranges: props.disabled_ranges, + attributes: props.attributes, + {props.children} + } + } + } +} + +#[component] +pub fn RangeCalendar(props: RangeCalendarProps) -> Element { + rsx! { + document::Link { rel: "stylesheet", href: asset!("./style.css") } + div { class: "calendar", + calendar::RangeCalendar { + selected_range: props.selected_range, + on_range_change: props.on_range_change, + on_format_weekday: props.on_format_weekday, + on_format_month: props.on_format_month, + view_date: props.view_date, + today: props.today, + on_view_change: props.on_view_change, + disabled: props.disabled, + first_day_of_week: props.first_day_of_week, + min_date: props.min_date, + max_date: props.max_date, + disabled_ranges: props.disabled_ranges, attributes: props.attributes, {props.children} } @@ -104,3 +131,8 @@ pub fn CalendarGrid(props: CalendarGridProps) -> Element { pub fn CalendarMonthTitle(props: CalendarMonthTitleProps) -> Element { calendar::CalendarMonthTitle(props) } + +#[component] +pub fn CalendarDay(props: CalendarDayProps) -> Element { + calendar::CalendarDay(props) +} diff --git a/preview/src/components/calendar/style.css b/preview/src/components/calendar/style.css index 48ffe8af..6703067e 100644 --- a/preview/src/components/calendar/style.css +++ b/preview/src/components/calendar/style.css @@ -1,198 +1,269 @@ /* Calendar Container */ .calendar { - border: 1px solid var(--primary-color-6); - border-radius: 8px; - background-color: var(--primary-color-2); - box-shadow: 0 2px 10px rgb(0 0 0 / 10%); - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, - Arial, sans-serif; + border: 1px solid var(--primary-color-6); + border-radius: 8px; + background-color: var(--primary-color-2); + box-shadow: 0 2px 10px rgb(0 0 0 / 10%); + font-family: + -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, + sans-serif; } /* Calendar Navigation */ .calendar-navigation { - display: flex; - align-items: center; - justify-content: space-between; - padding: 0.75rem 0.75rem 0.25rem; + display: flex; + align-items: center; + justify-content: space-between; + padding: 0.75rem 0.75rem 0.25rem; } .calendar-nav-title { - color: var(--secondary-color-4); - font-size: 16px; - font-weight: 600; + color: var(--secondary-color-4); + font-size: 16px; + font-weight: 600; } .calendar-nav-prev, .calendar-nav-next { - display: flex; - width: 1.75rem; - height: 1.75rem; - align-items: center; - justify-content: center; - border: 1px solid var(--primary-color-6); - border-radius: 0.5rem; - background-color: var(--light, transparent) - var(--dark, var(--primary-color-3)); - color: var(--secondary-color-5); - cursor: pointer; - font-size: 1rem; + display: flex; + width: 1.75rem; + height: 1.75rem; + align-items: center; + justify-content: center; + border: 1px solid var(--primary-color-6); + border-radius: 0.5rem; + background-color: var(--light, transparent) + var(--dark, var(--primary-color-3)); + color: var(--secondary-color-5); + cursor: pointer; + font-size: 1rem; } .calendar-nav-prev:hover, .calendar-nav-next:hover { - border-color: var(--primary-color-7); - background-color: var(--primary-color-4); - color: var(--secondary-color-4); + border-color: var(--primary-color-7); + background-color: var(--primary-color-4); + color: var(--secondary-color-4); } .calendar-nav-prev:focus-visible, .calendar-nav-next:focus-visible { - box-shadow: 0 0 0 2px var(--focused-border-color); + box-shadow: 0 0 0 2px var(--focused-border-color); +} + +.calendar-nav-prev:disabled, +.calendar-nav-next:disabled { + border-color: var(--primary-color-5); + background-color: var(--primary-color-2); + color: var(--secondary-color-3); + cursor: not-allowed; } /* Calendar Grid */ .calendar-grid { - width: 100%; - padding: 0.5rem; + width: 100%; + padding: 0.5rem; } .calendar-grid-header { - display: flex; - flex-direction: row; - margin-bottom: 8px; + display: flex; + flex-direction: row; + margin-bottom: 8px; } .calendar-grid-day-header { - width: 2rem; - color: var(--secondary-color-5); - font-size: 12px; - font-weight: 300; - text-align: center; + width: 2rem; + color: var(--secondary-color-5); + font-size: 12px; + font-weight: 300; + text-align: center; } .calendar-grid-body { - display: flex; - width: 100%; - flex-direction: column; - gap: 0.25rem; + display: flex; + width: 100%; + flex-direction: column; + gap: 0.25rem; } .calendar-grid-cell { - width: 2rem; - border: none; - border-radius: 0.5rem; - aspect-ratio: 1; - background: none; - color: var(--secondary-color-4); - cursor: pointer; - font-size: 14px; + width: 2rem; + border: none; + aspect-ratio: 1; + background: none; + color: var(--secondary-color-4); + cursor: pointer; + font-size: 14px; + border-radius: 0.5rem; } .calendar-grid-cell[data-month="current"]:not([data-disabled="true"]):hover { - background-color: var(--primary-color-4); + background-color: var(--primary-color-4); } .calendar-grid-cell[data-month="current"]:focus-visible { - outline: 2px solid var(--focused-border-color); - outline-offset: 2px; + outline: 2px solid var(--focused-border-color); + outline-offset: 2px; } .calendar-grid-cell[data-month="last"], .calendar-grid-cell[data-month="next"], .calendar-grid-cell[data-disabled="true"] { - color: var(--secondary-color-5); - cursor: not-allowed; + color: var(--secondary-color-5); + cursor: not-allowed; +} + +.calendar-grid-cell[data-month="last"][data-selected="true"], +.calendar-grid-cell[data-month="next"][data-selected="true"] { + background-color: var(--secondary-color-6); } .calendar-grid-cell[data-month="current"][data-selected="true"] { - background-color: var(--secondary-color-2); - color: var(--primary-color); + background-color: var(--secondary-color-2); + color: var(--primary-color); +} + +.calendar-grid-cell[data-month="current"][data-unavailable="true"] { + color: var(--secondary-color-6); + text-decoration: line-through; + cursor: not-allowed; +} + +.calendar-grid-week td { + padding-left: 0; + padding-right: 0; +} + +.calendar-grid-week td:first-child .calendar-grid-cell { + border-top-left-radius: 0.5rem; + border-bottom-left-radius: 0.5rem; +} + +.calendar-grid-week td:last-child .calendar-grid-cell { + border-top-right-radius: 0.5rem; + border-bottom-right-radius: 0.5rem; +} + +.calendar-grid-cell[data-month="last"][data-selection-between="true"], +.calendar-grid-cell[data-month="next"][data-selection-between="true"] { + background-color: var(--primary-color-5); + color: var(--secondary-color-5); + border-radius: 0; +} + +.calendar-grid-cell[data-month="current"][data-selection-between="true"] { + background-color: var(--primary-color-5); + color: var(--secondary-color-4); + border-radius: 0; +} + +td:has(.calendar-grid-cell[data-selection-start="true"]) { + background-color: var(--primary-color-5); + border-top-left-radius: 0.5rem; + border-bottom-left-radius: 0.5rem; + padding: 0; + margin-top: 1; + margin-bottom: 1; +} + +td:has(.calendar-grid-cell[data-selection-end="true"]) { + background-color: var(--primary-color-5); + border-top-right-radius: 0.5rem; + border-bottom-right-radius: 0.5rem; + padding: 0; + margin-top: 1; + margin-bottom: 1; } .calendar-grid-cell[data-month="current"][data-selected="true"]:hover { - background-color: var(--light, var(--secondary-color-2)) - var(--dark, var(--primary-color-5)); - color: var(--light, var(--primary-color)) - var(--dark, var(--secondary-color-1)); - font-weight: var(--light, 550) var(--dark, inherit); + background-color: var(--light, var(--secondary-color-2)) + var(--dark, var(--primary-color-5)); + color: var(--light, var(--primary-color)) + var(--dark, var(--secondary-color-1)); + font-weight: var(--light, 550) var(--dark, inherit); } .calendar-grid-cell[data-month="current"][data-today="true"]:not( - [data-selected="true"] - ) { - background-color: var(--primary-color-5); + [data-selected="true"] + ) { + background-color: var(--primary-color-5); } .calendar-grid-weeknum { - border-radius: 0.5rem; - background-color: var(--primary-color); - color: var(--secondary-color-5); - font-size: 12px; + border-radius: 0.5rem; + background-color: var(--primary-color); + color: var(--secondary-color-5); + font-size: 12px; } /* Calendar with week numbers */ .calendar-grid-week { - display: flex; - width: 100%; - flex-direction: row; + display: flex; + width: 100%; + flex-direction: row; } /* Calendar states */ .calendar[data-disabled="true"] { - opacity: 0.6; - pointer-events: none; + opacity: 0.6; + pointer-events: none; } .calendar-next-month-icon, .calendar-previous-month-icon { - width: 20px; - height: 20px; - fill: none; - stroke: currentcolor; - stroke-linecap: round; - stroke-linejoin: round; - stroke-width: 2; + width: 20px; + height: 20px; + fill: none; + stroke: currentcolor; + stroke-linecap: round; + stroke-linejoin: round; + stroke-width: 2; } -.calendar-month-select-container, .calendar-year-select-container { - position: relative; +.calendar-month-select-container, +.calendar-year-select-container { + position: relative; } -.calendar-month-select-container:has(:focus-visible), .calendar-year-select-container:has(:focus-visible) { - border-radius: 0.5rem; - outline: 2px solid var(--focused-border-color); +.calendar-month-select-container:has(:focus-visible), +.calendar-year-select-container:has(:focus-visible) { + border-radius: 0.5rem; + outline: 2px solid var(--focused-border-color); } - -.calendar-month-select, .calendar-year-select { - position: absolute; - width: 100%; - height: 100%; - padding: .25rem; - margin: 0; - inset: 0; - opacity: 0; +.calendar-month-select, +.calendar-year-select { + position: absolute; + width: 100%; + height: 100%; + padding: 0.25rem; + margin: 0; + inset: 0; + opacity: 0; } -.calendar-month-select-value, .calendar-year-select-value { - display: inline-flex; - align-items: center; - justify-content: center; - padding: .25rem; - border: none; - background-color: transparent; - color: var(--secondary-color-4); - cursor: pointer; - font-size: 1rem; - transition: background-color 0.2s ease, color 0.2s ease; +.calendar-month-select-value, +.calendar-year-select-value { + display: inline-flex; + align-items: center; + justify-content: center; + padding: 0.25rem; + border: none; + background-color: transparent; + color: var(--secondary-color-4); + cursor: pointer; + font-size: 1rem; + transition: + background-color 0.2s ease, + color 0.2s ease; } .select-expand-icon { - width: 20px; - height: 20px; - fill: none; - stroke: var(--secondary-color-4); - stroke-linecap: round; - stroke-linejoin: round; - stroke-width: 2; -} \ No newline at end of file + width: 20px; + height: 20px; + fill: none; + stroke: var(--secondary-color-4); + stroke-linecap: round; + stroke-linejoin: round; + stroke-width: 2; +} diff --git a/preview/src/components/calendar/variants/range/mod.rs b/preview/src/components/calendar/variants/range/mod.rs new file mode 100644 index 00000000..917e49cb --- /dev/null +++ b/preview/src/components/calendar/variants/range/mod.rs @@ -0,0 +1,38 @@ +use super::super::component::*; +use dioxus::prelude::*; +use time::{macros::date, Date, UtcDateTime}; + +use dioxus_primitives::calendar::DateRange; + +#[component] +pub fn Demo() -> Element { + let mut selected_range = use_signal(|| None::); + let mut view_date = use_signal(|| UtcDateTime::now().date()); + rsx! { + div { class: "calendar-example", style: "padding: 20px;", + RangeCalendar { + selected_range: selected_range(), + on_range_change: move |range| { + tracing::info!("Selected range: {:?}", range); + selected_range.set(range); + }, + view_date: view_date(), + on_view_change: move |new_view: Date| { + tracing::info!("View changed to: {}-{}", new_view.year(), new_view.month()); + view_date.set(new_view); + }, + min_date: date!(1995 - 07 - 21), + max_date: date!(2035 - 09 - 11), + CalendarHeader { + CalendarNavigation { + CalendarPreviousMonthButton {} + CalendarSelectMonth {} + CalendarSelectYear {} + CalendarNextMonthButton {} + } + } + CalendarGrid {} + } + } + } +} diff --git a/preview/src/components/calendar/variants/unavailable_dates/mod.rs b/preview/src/components/calendar/variants/unavailable_dates/mod.rs new file mode 100644 index 00000000..b243c7f9 --- /dev/null +++ b/preview/src/components/calendar/variants/unavailable_dates/mod.rs @@ -0,0 +1,50 @@ +use super::super::component::*; +use dioxus::prelude::*; +use time::{ext::NumericalDuration, macros::date, Date, UtcDateTime}; + +use dioxus_primitives::calendar::DateRange; + +#[component] +pub fn Demo() -> Element { + let mut selected_range = use_signal(|| None::); + + let now = UtcDateTime::now().date(); + let mut view_date = use_signal(|| now); + + let disabled_ranges = use_signal(|| { + vec![ + DateRange::new(now, now.saturating_add(3.days())), + DateRange::new(now.saturating_add(15.days()), now.saturating_add(18.days())), + DateRange::new(now.saturating_add(22.days()), now.saturating_add(23.days())), + ] + }); + + rsx! { + div { class: "calendar-example", style: "padding: 20px;", + RangeCalendar { + selected_range: selected_range(), + on_range_change: move |range| { + tracing::info!("Selected range: {:?}", range); + selected_range.set(range); + }, + view_date: view_date(), + on_view_change: move |new_view: Date| { + tracing::info!("View changed to: {}-{}", new_view.year(), new_view.month()); + view_date.set(new_view); + }, + min_date: date!(1995 - 07 - 21), + max_date: date!(2035 - 09 - 11), + disabled_ranges: disabled_ranges(), + CalendarHeader { + CalendarNavigation { + CalendarPreviousMonthButton {} + CalendarSelectMonth {} + CalendarSelectYear {} + CalendarNextMonthButton {} + } + } + CalendarGrid {} + } + } + } +} diff --git a/preview/src/components/mod.rs b/preview/src/components/mod.rs index 53aa0a9a..887b2bbe 100644 --- a/preview/src/components/mod.rs +++ b/preview/src/components/mod.rs @@ -62,7 +62,7 @@ examples!( aspect_ratio, avatar, button, - calendar[simple, internationalized], + calendar[simple, internationalized, range, unavailable_dates], checkbox, collapsible, context_menu, diff --git a/primitives/src/calendar.rs b/primitives/src/calendar.rs index a9237a71..0fad46d6 100644 --- a/primitives/src/calendar.rs +++ b/primitives/src/calendar.rs @@ -2,6 +2,7 @@ use dioxus::prelude::*; use std::{ + collections::HashSet, fmt::{self, Display}, rc::Rc, }; @@ -90,6 +91,18 @@ impl Iterator for WeekdaySetIter { } } +pub(crate) fn weekday_abbreviation(weekday: Weekday) -> &'static str { + match weekday { + Weekday::Monday => "Mo", + Weekday::Tuesday => "Tu", + Weekday::Wednesday => "We", + Weekday::Thursday => "Th", + Weekday::Friday => "Fr", + Weekday::Saturday => "Sa", + Weekday::Sunday => "Su", + } +} + // The number of days since the first weekday of current date fn days_since(date: Date, weekday: Weekday) -> i64 { let lhs = date.replace_day(1).unwrap().weekday() as i64; @@ -141,14 +154,120 @@ fn replace_month(date: Date, month: Month) -> Date { .expect("invalid or out-of-range date") } -/// The context provided by the [`Calendar`] component to its children. +/// Calendar date range +#[derive(Copy, Clone, Debug)] +pub struct DateRange { + /// The start date of the range + start: Date, + /// The end date of the range + end: Date, +} + +impl DateRange { + /// Create a new date range + pub fn new(start: Date, end: Date) -> Self { + if start <= end { + Self { start, end } + } else { + Self { + start: end, + end: start, + } + } + } + + fn contains(&self, date: Date) -> bool { + self.start <= date && date <= self.end + } + + fn contained_in_interval(&self, date: Date) -> bool { + self.start < date && date < self.end + } + + fn clamp(&self, date: Date) -> Date { + date.clamp(self.start, self.end) + } +} + +impl Display for DateRange { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{} - {}", self.start, self.end) + } +} + +#[derive(Debug, Clone, PartialEq)] +struct AvailibleRanges { + /// A sorted list of dates. Values after an odd number of elements are disabled. + changes: Vec, +} + +impl AvailibleRanges { + fn new(disabled_ranges: &[DateRange]) -> Self { + let mut sorted_range: Vec<_> = disabled_ranges + .iter() + .enumerate() + .flat_map(|(index, date)| [(index, date.start), (index, date.end)]) + .collect(); + + sorted_range.sort_by_key(|(_, date)| *date); + + // Merge any overlapping ranges + let mut open_ranges = HashSet::new(); + let mut deduped_ranges = Vec::with_capacity(sorted_range.len()); + + for (index, date) in sorted_range { + let end_of_range = open_ranges.remove(&index); + if open_ranges.is_empty() { + deduped_ranges.push(date); + } + if !end_of_range { + open_ranges.insert(index); + } + } + + Self { + changes: deduped_ranges, + } + } + + fn valid_interval(&self, date: Date) -> bool { + match self.changes.binary_search(&date) { + Ok(_) => false, + Err(index) => index % 2 == 0, + } + } + + fn available_range(&self, date: Date, min_date: Date, max_date: Date) -> Option { + let date_index = self.changes.binary_search(&date).err()?; + + let valid = date_index % 2 == 0; + if !valid { + return None; + } + + let start = date_index + .checked_sub(1) + .and_then(|index| self.changes.get(index).copied()) + .map(|start| start.next_day().unwrap_or(start)) + .unwrap_or(min_date); + let end = self + .changes + .get(date_index) + .copied() + .map(|end| end.previous_day().unwrap_or(end)) + .unwrap_or(max_date); + + Some(DateRange::new(start, end)) + } +} + +/// The base context provided by the [`Calendar`] and the [`RangeCalendar`] component to its children. #[derive(Copy, Clone)] -pub struct CalendarContext { +pub struct BaseCalendarContext { // State - selected_date: ReadSignal>, - set_selected_date: Callback>, focused_date: Signal>, view_date: ReadSignal, + available_ranges: Memo, set_view_date: Callback, format_weekday: Callback, format_month: Callback, @@ -161,17 +280,7 @@ pub struct CalendarContext { max_date: Date, } -impl CalendarContext { - /// Get the currently selected date - pub fn selected_date(&self) -> Option { - self.selected_date.cloned() - } - - /// Set the selected date - pub fn set_selected_date(&self, date: Option) { - (self.set_selected_date)(date); - } - +impl BaseCalendarContext { /// Get the currently focused date pub fn focused_date(&self) -> Option { self.focused_date.cloned() @@ -196,17 +305,45 @@ impl CalendarContext { pub fn is_disabled(&self) -> bool { self.disabled.cloned() } + + /// Check if the selected date is unavailable + pub fn is_unavailable(&self, date: Date) -> bool { + !self.available_ranges.read().valid_interval(date) + } + + /// Check if a date is focused + pub fn is_focused(&self, date: Date) -> bool { + self.focused_date().is_some_and(|d| d == date) + } + + /// Return available date range by given date + pub fn available_range(&self) -> Option { + try_consume_context::().and_then(|ctx| { + ctx.anchor_date.cloned().and_then(|date| { + self.available_ranges + .read() + .available_range(date, self.min_date, self.max_date) + }) + }) + } } -pub(crate) fn weekday_abbreviation(weekday: Weekday) -> &'static str { - match weekday { - Weekday::Monday => "Mo", - Weekday::Tuesday => "Tu", - Weekday::Wednesday => "We", - Weekday::Thursday => "Th", - Weekday::Friday => "Fr", - Weekday::Saturday => "Sa", - Weekday::Sunday => "Su", +/// The context provided by the [`Calendar`] component to its children. +#[derive(Copy, Clone)] +pub struct CalendarContext { + selected_date: ReadSignal>, + set_selected_date: Callback>, +} + +impl CalendarContext { + /// Get the currently selected date + pub fn selected_date(&self) -> Option { + self.selected_date.cloned() + } + + /// Set the selected date + pub fn set_selected_date(&self, date: Option) { + (self.set_selected_date)(date); } } @@ -257,6 +394,10 @@ pub struct CalendarProps { #[props(default = date!(2050-12-31))] pub max_date: Date, + /// Unavailable dates + #[props(default)] + pub disabled_ranges: ReadSignal>, + /// Additional attributes to extend the calendar element #[props(extends = GlobalAttributes)] pub attributes: Vec, @@ -315,13 +456,265 @@ pub struct CalendarProps { /// - `data-disabled`: Indicates if the calendar is disabled. Possible values are `true` or `false`. #[component] pub fn Calendar(props: CalendarProps) -> Element { - // Create context provider for child components - let mut ctx = use_context_provider(|| CalendarContext { + let available_ranges = use_memo(move || AvailibleRanges::new(&props.disabled_ranges.read())); + + // Create base context provider for child components + let mut base_ctx = use_context_provider(|| BaseCalendarContext { + focused_date: Signal::new(props.selected_date.cloned()), + view_date: props.view_date, + set_view_date: props.on_view_change, + available_ranges, + format_weekday: props.on_format_weekday, + format_month: props.on_format_month, + disabled: props.disabled, + today: props.today, + first_day_of_week: props.first_day_of_week, + min_date: props.min_date, + max_date: props.max_date, + }); + // Create Calendar context provider for child components + use_context_provider(|| CalendarContext { selected_date: props.selected_date, set_selected_date: props.on_date_change, - focused_date: Signal::new(props.selected_date.cloned()), + }); + + rsx! { + div { + role: "application", + aria_label: "Calendar", + "data-disabled": (props.disabled)(), + onkeydown: move |e| { + let Some(focused_date) = (base_ctx.focused_date)() else { + return; + }; + let mut set_focused_date = |new_date: Option| { + // Make sure the view date month is the same as the focused date + let mut view_date = (base_ctx.view_date)(); + if let Some(date) = new_date { + if date.month() != view_date.month() { + view_date = date.replace_day(1).unwrap(); + (base_ctx.set_view_date)(view_date); + } + } + + match new_date { + Some(date) => { + if base_ctx.min_date <= date && date <= base_ctx.max_date { + base_ctx.focused_date.set(new_date); + } + }, + None => base_ctx.focused_date.set(None) + } + }; + match e.key() { + Key::ArrowLeft => { + e.prevent_default(); + set_focused_date(focused_date.previous_day()); + } + Key::ArrowRight => { + e.prevent_default(); + set_focused_date(focused_date.next_day()); + } + Key::ArrowUp => { + e.prevent_default(); + if e.modifiers().shift() { + if let Some(date) = previous_month(focused_date) { + set_focused_date(Some(date)); + } + } else { + // Otherwise, move to the previous week + set_focused_date(Some(focused_date.saturating_sub(7.days()))); + } + } + Key::ArrowDown => { + e.prevent_default(); + if e.modifiers().shift() { + if let Some(date) = next_month(focused_date) { + set_focused_date(Some(date)); + } + } else { + // Otherwise, move to the next week + set_focused_date(Some(focused_date.saturating_add(7.days()))); + } + } + _ => {} + } + }, + ..props.attributes, + + {props.children} + } + } +} + +/// The context provided by the [`RangeCalendar`] component to its children. +#[derive(Copy, Clone)] +pub struct RangeCalendarContext { + // The date that the user clicked on to begin range selection + anchor_date: Signal>, + // Currently highlighted date range + highlighted_range: Signal>, + set_selected_range: Callback>, +} + +impl RangeCalendarContext { + /// Set the selected date + pub fn set_selected_date(&mut self, date: Option) { + match (self.anchor_date)() { + Some(anchor) => { + if let Some(date) = date { + self.anchor_date.set(None); + + let range = DateRange::new(date, anchor); + self.set_selected_range.call(Some(range)); + self.highlighted_range.set(Some(range)); + } + } + None => { + self.anchor_date.set(date); + + let range = date.map(|d| DateRange::new(d, d)); + self.highlighted_range.set(range); + } + } + } + + /// Set the selected date range by hovered date + pub fn set_hovered_date(&mut self, date: Date) { + if let Some(anchor) = (self.anchor_date)() { + let range = DateRange::new(anchor, date); + self.highlighted_range.set(Some(range)); + } + } + + /// Set previous selected range + pub fn reset_selection(&mut self, range: Option) { + self.anchor_date.set(None); + self.highlighted_range.set(range); + } +} + +/// The props for the [`RangeCalendar`] component. +#[derive(Props, Clone, PartialEq)] +pub struct RangeCalendarProps { + /// The selected range + #[props(default)] + pub selected_range: ReadSignal>, + + /// Callback when selected date range changes + #[props(default)] + pub on_range_change: Callback>, + + /// Callback when display weekday + #[props(default = Callback::new(|weekday: Weekday| weekday_abbreviation(weekday).to_string()))] + pub on_format_weekday: Callback, + + /// Callback when display month + #[props(default = Callback::new(|month: Month| month.to_string()))] + pub on_format_month: Callback, + + /// The month being viewed + #[props(default = ReadSignal::new(Signal::new(UtcDateTime::now().date())))] + pub view_date: ReadSignal, + + /// The current date (used for highlighting today) + #[props(default = UtcDateTime::now().date())] + pub today: Date, + + /// Callback when view date changes + #[props(default)] + pub on_view_change: Callback, + + /// Whether the calendar is disabled + #[props(default)] + pub disabled: ReadSignal, + + /// First day of the week + #[props(default = Weekday::Sunday)] + pub first_day_of_week: Weekday, + + /// Lower limit of the range of available dates + #[props(default = date!(1925-01-01))] + pub min_date: Date, + + /// Upper limit of the range of available dates + #[props(default = date!(2050-12-31))] + pub max_date: Date, + + /// Unavailable dates + #[props(default)] + pub disabled_ranges: ReadSignal>, + + /// Additional attributes to extend the calendar element + #[props(extends = GlobalAttributes)] + pub attributes: Vec, + + /// The children of the calendar element + pub children: Element, +} + +/// # RangeCalendar +/// +/// The [`RangeCalendar`] component provides an accessible calendar interface with arrow key navigation, month switching, and date selection. +/// +/// ## Example +/// ```rust +/// use dioxus::prelude::*; +/// use dioxus_primitives::calendar::*; +/// use time::{Date, Month, UtcDateTime}; +/// #[component] +/// fn Demo() -> Element { +/// let mut selected_range = use_signal(|| None::); +/// let mut view_date = use_signal(|| UtcDateTime::now().date()); +/// rsx! { +/// RangeCalendar { +/// selected_range: selected_range(), +/// on_range_change: move |range| { +/// tracing::info!("Selected range: {:?}", range); +/// selected_range.set(range); +/// }, +/// view_date: view_date(), +/// on_view_change: move |new_view: Date| { +/// tracing::info!("View changed to: {}-{}", new_view.year(), new_view.month()); +/// view_date.set(new_view); +/// }, +/// CalendarHeader { +/// CalendarNavigation { +/// CalendarPreviousMonthButton { +/// "<" +/// } +/// CalendarMonthTitle {} +/// CalendarNextMonthButton { +/// ">" +/// } +/// } +/// } +/// CalendarGrid {} +/// } +/// } +/// } +/// ``` +/// +/// # Styling +/// +/// The [`RangeCalendar`] component defines the following data attributes you can use to control styling: +/// - `data-disabled`: Indicates if the calendar is disabled. Possible values are `true` or `false`. +#[component] +pub fn RangeCalendar(props: RangeCalendarProps) -> Element { + let focused_date = use_signal(|| { + let range = (props.selected_range)(); + range.map(|r| r.end) + }); + let anchor_date = use_signal(|| None::); + let highlighted_range = use_signal(|| (props.selected_range)()); + let available_ranges = use_memo(move || AvailibleRanges::new(&props.disabled_ranges.read())); + + // Create base context provider for child components + let mut base_ctx = use_context_provider(|| BaseCalendarContext { + focused_date, view_date: props.view_date, set_view_date: props.on_view_change, + available_ranges, format_weekday: props.on_format_weekday, format_month: props.on_format_month, disabled: props.disabled, @@ -331,32 +724,54 @@ pub fn Calendar(props: CalendarProps) -> Element { max_date: props.max_date, }); + // Create RangeCalendar context provider for child components + let mut ctx = use_context_provider(|| RangeCalendarContext { + anchor_date, + highlighted_range, + set_selected_range: props.on_range_change, + }); + rsx! { div { role: "application", aria_label: "Calendar", "data-disabled": (props.disabled)(), onkeydown: move |e| { - let Some(focused_date) = (ctx.focused_date)() else { + let Some(mut focused_date) = (base_ctx.focused_date)() else { return; }; + + // force hover day as focus + if let (Some(range), Some(date)) = ((ctx.highlighted_range)(), (ctx.anchor_date)()) { + if date != range.start { + focused_date = range.start + } else { + focused_date = range.end + } + }; + let mut set_focused_date = |new_date: Option| { // Make sure the view date month is the same as the focused date - let mut view_date = (ctx.view_date)(); + let mut view_date = (base_ctx.view_date)(); if let Some(date) = new_date { if date.month() != view_date.month() { view_date = date.replace_day(1).unwrap(); - (ctx.set_view_date)(view_date); + (base_ctx.set_view_date)(view_date); } } match new_date { Some(date) => { - if ctx.min_date <= date && date <= ctx.max_date { - ctx.focused_date.set(new_date); + if base_ctx.min_date <= date && date <= base_ctx.max_date { + base_ctx.focused_date.set(new_date); + let date = match base_ctx.available_range() { + Some(range) => range.clamp(date), + None => date, + }; + ctx.set_hovered_date(date); } }, - None => ctx.focused_date.set(None) + None => base_ctx.focused_date.set(None) } }; match e.key() { @@ -390,6 +805,9 @@ pub fn Calendar(props: CalendarProps) -> Element { set_focused_date(Some(focused_date.saturating_add(7.days()))); } } + Key::Escape => { + ctx.reset_selection((props.selected_range)()); + } _ => {} } }, @@ -595,7 +1013,7 @@ pub struct CalendarPreviousMonthButtonProps { /// ``` #[component] pub fn CalendarPreviousMonthButton(props: CalendarPreviousMonthButtonProps) -> Element { - let ctx: CalendarContext = use_context(); + let ctx: BaseCalendarContext = use_context(); // disable previous button when we reach the limit let button_disabled = use_memo(move || { // Get the current view date from context @@ -605,6 +1023,13 @@ pub fn CalendarPreviousMonthButton(props: CalendarPreviousMonthButtonProps) -> E None => true, } }); + // disable previous button when the current selection range does not include the previous month + let navigate_disabled = use_memo(move || { + // Get the current view date from context + let view_date = (ctx.view_date)(); + ctx.available_range() + .is_some_and(|range| range.start.month() == view_date.month()) + }); // Handle navigation to previous month let handle_prev_month = move |e: Event| { @@ -621,7 +1046,7 @@ pub fn CalendarPreviousMonthButton(props: CalendarPreviousMonthButtonProps) -> E aria_label: "Previous month", type: "button", onclick: handle_prev_month, - disabled: (ctx.disabled)() || button_disabled(), + disabled: (ctx.disabled)() || button_disabled() || navigate_disabled(), ..props.attributes, {props.children} @@ -687,7 +1112,7 @@ pub struct CalendarNextMonthButtonProps { /// ``` #[component] pub fn CalendarNextMonthButton(props: CalendarNextMonthButtonProps) -> Element { - let ctx: CalendarContext = use_context(); + let ctx: BaseCalendarContext = use_context(); // disable next button when we reach the limit let button_disabled = use_memo(move || { // Get the current view date from context @@ -700,6 +1125,13 @@ pub fn CalendarNextMonthButton(props: CalendarNextMonthButtonProps) -> Element { None => true, } }); + // disable next button when the current selection range does not include the next month + let navigate_disabled = use_memo(move || { + // Get the current view date from context + let view_date = (ctx.view_date)(); + ctx.available_range() + .is_some_and(|range| range.end.month() == view_date.month()) + }); // Handle navigation to next month let handle_next_month = move |e: Event| { @@ -716,7 +1148,7 @@ pub fn CalendarNextMonthButton(props: CalendarNextMonthButtonProps) -> Element { aria_label: "Next month", type: "button", onclick: handle_next_month, - disabled: (ctx.disabled)() || button_disabled(), + disabled: (ctx.disabled)() || button_disabled() || navigate_disabled(), ..props.attributes, {props.children} @@ -780,7 +1212,7 @@ pub struct CalendarMonthTitleProps { /// ``` #[component] pub fn CalendarMonthTitle(props: CalendarMonthTitleProps) -> Element { - let ctx: CalendarContext = use_context(); + let ctx: BaseCalendarContext = use_context(); // Format the current month and year let month_year = use_memo(move || { let view_date = (ctx.view_date)(); @@ -873,7 +1305,7 @@ pub struct CalendarGridProps { /// - `data-month`: The relative month of the date. Possible values are `last`, `current`, or `next` #[component] pub fn CalendarGrid(props: CalendarGridProps) -> Element { - let ctx: CalendarContext = use_context(); + let ctx: BaseCalendarContext = use_context(); // We'll use the view_date from context in the memo below @@ -1025,7 +1457,7 @@ pub struct CalendarSelectMonthProps { /// ``` #[component] pub fn CalendarSelectMonth(props: CalendarSelectMonthProps) -> Element { - let calendar: CalendarContext = use_context(); + let calendar: BaseCalendarContext = use_context(); let view_date = calendar.view_date(); let month = view_date.month(); @@ -1141,7 +1573,7 @@ pub struct CalendarSelectYearProps { /// ``` #[component] pub fn CalendarSelectYear(props: CalendarSelectYearProps) -> Element { - let calendar: CalendarContext = use_context(); + let calendar: BaseCalendarContext = use_context(); let view_date = calendar.view_date(); let year = view_date.year(); @@ -1200,6 +1632,12 @@ enum RelativeMonth { Next, } +impl RelativeMonth { + fn current_month(&self) -> bool { + *self == RelativeMonth::Current + } +} + impl Display for RelativeMonth { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { @@ -1221,49 +1659,120 @@ fn aria_label(date: &Date) -> String { ) } +/// The props for the [`CalendarDay`] component. #[derive(Props, Clone, Debug, PartialEq)] -struct CalendarDayProps { +pub struct CalendarDayProps { date: Date, + /// Additional attributes to extend the calendar day element #[props(extends = GlobalAttributes)] pub attributes: Vec, } +/// # CalendarDay +/// +/// The [`CalendarDay`] component provides an accessible calendar interface for a date +/// +/// This must be used inside a [`CalendarGrid`] component. +/// +/// ## Example +/// ```rust +/// use dioxus::prelude::*; +/// use dioxus_primitives::calendar::*; +/// use time::{Date, Month, UtcDateTime}; +/// #[component] +/// fn Demo() -> Element { +/// let mut selected_range = use_signal(|| None::); +/// let mut view_date = use_signal(|| UtcDateTime::now().date()); +/// rsx! { +/// RangeCalendar { +/// selected_range: selected_range(), +/// on_range_change: move |range| { +/// tracing::info!("Selected range: {:?}", range); +/// selected_range.set(range); +/// }, +/// view_date: view_date(), +/// on_view_change: move |new_view: Date| { +/// tracing::info!("View changed to: {}-{}", new_view.year(), new_view.month()); +/// view_date.set(new_view); +/// }, +/// CalendarHeader { +/// CalendarNavigation { +/// CalendarPreviousMonthButton { +/// "<" +/// } +/// CalendarMonthTitle {} +/// CalendarNextMonthButton { +/// ">" +/// } +/// } +/// } +/// CalendarGrid {} +/// } +/// } +/// } +/// ``` +/// +/// # Styling +/// +/// The [`CalendarDay`] component defines the following data attributes you can use to control styling: +/// - `data-disabled`: Indicates if the calendar is disabled. Possible values are `true` or `false`. +/// - `data-unavailable`: Indicates if the date is unavailable. Possible values are `true` or `false`. +/// - `data-today`: Indicates if the cell is today. Possible values are `true` or `false`. +/// - `data-month`: The relative month of the date. Possible values are `last`, +/// - `data-selected`: Indicates if the cell is selected. Possible values are `true` or `false`. +/// - `data-selection-start`: Indicates if cell is the first date in a range selection. Possible values are `true` or `false`. +/// - `data-selection-between`: Indicates if a date interval contains a cell. Possible values are `true` or `false`. +/// - `data-selection-end`: Indicates if cell is the last date in a range selection. Possible values are `true` or `false`. #[component] -fn CalendarDay(props: CalendarDayProps) -> Element { - let CalendarDayProps { date, attributes } = props; - let mut ctx: CalendarContext = use_context(); - let view_date = (ctx.view_date)(); - let day = date.day(); - let month = { - if date < ctx.min_date { - RelativeMonth::Last - } else if date > ctx.max_date { - RelativeMonth::Next - } else { - let lhs = date.month() as u8; - let rhs = view_date.month() as u8; - match lhs.cmp(&rhs) { - std::cmp::Ordering::Less => RelativeMonth::Last, - std::cmp::Ordering::Equal => RelativeMonth::Current, - std::cmp::Ordering::Greater => RelativeMonth::Next, - } +pub fn CalendarDay(props: CalendarDayProps) -> Element { + let single_context = try_use_context::().is_some(); + + if single_context { + rsx! { + SingleCalendarDay { date: props.date, attributes: props.attributes.clone() } } - }; - let in_current_month = month == RelativeMonth::Current; - let is_selected = move || (ctx.selected_date)().is_some_and(|d| d == date); - let is_focused = move || (ctx.focused_date)().is_some_and(|d| d == date); - let is_today = date == ctx.today; + } else { + rsx! { + RangeCalendarDay { date: props.date, attributes: props.attributes.clone() } + } + } +} - // Handle day selection - let mut handle_day_select = move |day: u8| { - if !(ctx.disabled)() { - let view_date = (ctx.view_date)(); - let date = view_date.replace_day(day).unwrap(); - ctx.set_selected_date.call((!is_selected()).then_some(date)); - ctx.focused_date.set(Some(date)); +fn relative_calendar_month( + date: Date, + base_ctx: &BaseCalendarContext, + view_date: Date, +) -> RelativeMonth { + if date < base_ctx.min_date { + RelativeMonth::Last + } else if date > base_ctx.max_date { + RelativeMonth::Next + } else { + let lhs = date.month() as u8; + let rhs = view_date.month() as u8; + match lhs.cmp(&rhs) { + std::cmp::Ordering::Less => RelativeMonth::Last, + std::cmp::Ordering::Equal => RelativeMonth::Current, + std::cmp::Ordering::Greater => RelativeMonth::Next, } - }; + } +} + +fn is_between(date: Date, range: Option) -> bool { + range.is_some_and(|r| r.contained_in_interval(date)) +} + +fn is_start(date: Date, range: Option) -> bool { + range.is_some_and(|r| r.start == date && date != r.end) +} + +fn is_end(date: Date, range: Option) -> bool { + range.is_some_and(|r| r.end == date && date != r.start) +} +fn use_day_mounted_ref( + mut is_focused: impl FnMut() -> bool + 'static, +) -> impl FnMut(MountedEvent) + 'static { let mut day_ref: Signal>> = use_signal(|| None); use_effect(move || { if let Some(day) = day_ref() { @@ -1274,9 +1783,45 @@ fn CalendarDay(props: CalendarDayProps) -> Element { } } }); + move |e| day_ref.set(Some(e.data())) +} + +#[component] +fn SingleCalendarDay(props: CalendarDayProps) -> Element { + let CalendarDayProps { date, attributes } = props; + let mut base_ctx: BaseCalendarContext = use_context(); + let day = date.day(); + let view_date = (base_ctx.view_date)(); + let month = relative_calendar_month(date, &base_ctx, view_date); + let in_current_month = month.current_month(); + let is_focused = move || base_ctx.is_focused(date); + let is_today = date == base_ctx.today; + let is_unavailable = base_ctx.is_unavailable(date); + + let is_disabled = move || { + if (base_ctx.disabled)() { + return true; + } + + is_unavailable + }; + let onmounted = use_day_mounted_ref(is_focused); + + let ctx: CalendarContext = use_context(); + let is_selected = move || (ctx.selected_date)().is_some_and(|d| d == date); + + // Handle day selection + let mut handle_day_select = move |day: u8| { + if (base_ctx.disabled)() || is_unavailable { + return; + } + let view_date = (base_ctx.view_date)(); + let date = view_date.replace_day(day).unwrap(); + ctx.set_selected_date.call((!is_selected()).then_some(date)); + base_ctx.focused_date.set(Some(date)); + }; - let view_date = (ctx.view_date)(); - let focusable_date = (ctx.focused_date)() + let focusable_date = (base_ctx.focused_date)() .filter(|d| d.month() == view_date.month()) .or_else(|| { ctx.selected_date @@ -1297,6 +1842,8 @@ fn CalendarDay(props: CalendarDayProps) -> Element { aria_label: aria_label(&props.date), "data-today": is_today, "data-selected": is_selected(), + "data-unavailable": if is_unavailable { true }, + "data-disabled": is_disabled(), "data-month": "{month}", onclick: move |e| { e.prevent_default(); @@ -1306,10 +1853,107 @@ fn CalendarDay(props: CalendarDayProps) -> Element { }, onfocus: move |_| { if in_current_month { - ctx.focused_date.set(Some(date)); + base_ctx.focused_date.set(Some(date)); + } + }, + onmounted, + ..attributes, + {day.to_string()} + } + } +} + +#[component] +fn RangeCalendarDay(props: CalendarDayProps) -> Element { + let CalendarDayProps { date, attributes } = props; + let mut base_ctx: BaseCalendarContext = use_context(); + let day = date.day(); + let view_date = (base_ctx.view_date)(); + let month = relative_calendar_month(date, &base_ctx, view_date); + let in_current_month = month.current_month(); + let is_focused = move || base_ctx.is_focused(date); + let is_today = date == base_ctx.today; + let is_unavailable = base_ctx.is_unavailable(date); + + let is_disabled = move || { + if (base_ctx.disabled)() { + return true; + } + + is_unavailable + }; + let onmounted = use_day_mounted_ref(is_focused); + + let mut ctx: RangeCalendarContext = use_context(); + let is_selected = move || (ctx.highlighted_range)().is_some_and(|r| r.contains(date)); + let is_between = move || is_between(date, ctx.highlighted_range.cloned()); + let is_start = move || is_start(date, ctx.highlighted_range.cloned()); + let is_end = move || is_end(date, ctx.highlighted_range.cloned()); + + let clamp_date_to_available_range = move |date| { + let available_range = base_ctx.available_range(); + available_range.map_or(date, |range| range.clamp(date)) + }; + + // Handle day selection + let mut handle_day_select = move |day: u8| { + if is_disabled() || is_unavailable { + return; + } + + let view_date = (base_ctx.view_date)(); + let date = view_date + .replace_day(day) + .ok() + .map(clamp_date_to_available_range); + ctx.set_selected_date(date); + base_ctx.focused_date.set(date); + }; + + let focusable_date = (base_ctx.focused_date)() + .filter(|d| d.month() == view_date.month()) + .or_else(|| { + ctx.anchor_date + .cloned() + .filter(|d| d.month() == view_date.month()) + }) + .unwrap_or(view_date); + + rsx! { + button { + class: "calendar-grid-cell", + type: "button", + tabindex: if date == focusable_date { + "0" + } else { + "-1" + }, + aria_label: aria_label(&props.date), + "data-disabled": is_disabled(), + "data-today": if is_today { true }, + "data-selected": is_selected(), + "data-unavailable": if is_unavailable { true }, + "data-selection-start": if is_start() { true }, + "data-selection-between": if is_between() { true }, + "data-selection-end": if is_end() { true }, + "data-month": "{month}", + onclick: move |e| { + e.prevent_default(); + if in_current_month { + handle_day_select(day); + } + }, + onfocus: move |_| { + if in_current_month { + base_ctx.focused_date.set(Some(date)); + } + }, + onmouseover: move |_| { + if in_current_month { + ctx.set_hovered_date(clamp_date_to_available_range(date)); } }, - onmounted: move |e| day_ref.set(Some(e.data())), + onmounted, ..attributes, {day.to_string()} }